Search code examples
ruby-on-railshas-many-throughlink-to

Can't link to correct route using link_to


I am trying to link to the existing route /clients/:client_id/invoices/:id from my /clients/:client_id show page and cant work out how to do so.

I have a has_many through: relationship and here are my models

class Client < ActiveRecord::Base
has_many :invoices
has_many :items, through: :invoices

class Invoice < ActiveRecord::Base
belongs_to :user
belongs_to :client
has_many :items, :dependent => :destroy

accepts_nested_attributes_for :items, :reject_if => :all_blank, :allow_destroy => true

class Item < ActiveRecord::Base
belongs_to :invoice
belongs_to :client

My routes

resources :clients do
resources :invoices
end
resources :invoices

my client controllers show action

def show
@client = Client.find(params[:id])
@invoices = @client.invoices.build
end

And my clients show.html.erb

<div class="panel-body">
        <table class="table table-hover">
          <thead>
            <tr>
              <th>Sender</th>
              <th>Reciever</th>
              <th>Amount</th>
              <th>Currency</th>
              <th>Date</th>
              <th colspan="3"></th>
            </tr>
          </thead>              
          <tbody>              
          <% @client.invoices.each do |invoice| %>
              <tr>
                <td><%= invoice.sender %></td>
                <td><%= invoice.reciever %></td>
                <td><%= invoice.amount %></td>
                <td><%= invoice.currency %></td>
                <td><%= invoice.date %></td>
                <td><%= link_to 'Show', invoices_path(@clients, @invoice) %></td>
              </tr>                
          <% end %>  
          </tbody>
        </table>
      </div>

everytime I click the link_to show it routes me to /invoices I have tried a bunch of different link_to formats but I haven't been able to figure it out.


Solution

  • You are using wrong url_helper with wrong parameters. You should have:

    <td><%= link_to 'Show', client_invoice_path(@client, invoice) %></td>
    

    or

    <td><%= link_to 'Show', invoice_path(invoice) %></td>
    

    invoices_path is an url_helper generated by resources :invoices (the most outside one) and will route you to the index path for your InvoicesController (/invoices). If you pass an argument, it will be used for the format (/invoices.10 - quite common issue).

    All the routes generated by nested resources have a name consisting of both resources, like new_user_profile_path or client_invoice_type_path (triple nested).

    Note that your current route structure (same resources with two different paths) might make your controller logic more complex. It is usually sufficient to have a single route, pick one.