2015-04-22 15 views
6

Ich habe Ressourcen verschachtelt wie folgt:Rails: Route Helfer für verschachtelte Ressourcen

resources :categories do 
    resources :products 
end 

Nach dem Rails Guides,

Sie auch mit einer Reihe von Objekten verwenden url_for können, und Rails automatisch bestimmen, welche Route Sie wollen:

<%= link_to 'Ad details', url_for([@magazine, @ad]) %> 

In diesem Fall Rails werden sehen, dass @magazine ein Magazin und @ad ist ein n Ad und verwendet daher den Helfer magazin_ad_pfad. In Helfern wie link_to, können Sie einfach das Objekt anstelle des vollen url_for Anrufs angeben:

<%= link_to 'Ad details', [@magazine, @ad] %> 

Für andere Aktionen, müssen Sie nur den Namen der Aktion als das erste Element des Arrays einzufügen:

<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %> 

In meinem Fall habe ich den folgenden Code die voll funktionsfähig war:

<% @products.each do |product| %> 
    <tr> 
    <td><%= product.name %></td> 
    <td><%= link_to 'Show', category_product_path(product, category_id: product.category_id) %></td> 
    <td><%= link_to 'Edit', edit_category_product_path(product, category_id: product.category_id) %></td> 
    <td><%= link_to 'Destroy', category_product_path(product, category_id: product.category_id), method: :delete, data: { confirm: 'Are you sure?' } %></td> 
    </tr> 
<% end %> 

Natürlich ist es ein wenig zu ist ver Bose und ich wollte es mit dem oben genannten Trick aus Schienenführungen verkürzen.

Aber wenn ich änderte die anzeigen und bearbeiten Link wie folgt:

<% @products.each do |product| %> 
    <tr> 
    <td><%= product.name %></td> 
    <td><%= link_to 'Show', [product, product.category_id] %></td> 
    <td><%= link_to 'Edit', [:edit, product, product.category_id] %></td> 
    <td><%= link_to 'Destroy', category_product_path(product, category_id: product.category_id), method: :delete, data: { confirm: 'Are you sure?' } %></td> 
    </tr> 
<% end %> 

Keiner von ihnen nicht mehr funktioniert, und die Seiten beklagt das Gleiche:

NoMethodError in Products#index 
Showing /root/Projects/foo/app/views/products/index.html.erb where line #16 raised: 

undefined method `persisted?' for 3:Fixnum 

Was habe ich vermisst?

+2

Funktioniert es, wenn Sie '[product, product.category]' (für die 'Show' URL)? –

Antwort

5

Die Art und Weise, wie Rails "automatisch" den zu verwendenden Pfad erkennt, besteht darin, die Objekte zu prüfen, die Sie für ihre Klassen übergeben, und dann nach einem Controller zu suchen, dessen Name übereinstimmt. Sie müssen also sicherstellen, dass das, was Sie an den link_to Helfer übergeben, das eigentliche Modellobjekt ist, und nicht etwas wie category_id, das ist nur ein fixnum und hat daher keinen zugeordneten Controller.

<% @products.each do |product| %> 
    <tr> 
    <td><%= product.name %></td> 
    <td><%= link_to 'Show', [product.category, product] %></td> 
    <td><%= link_to 'Edit', [:edit, product.category, product] %></td> 
    <td><%= link_to 'Destroy', [product.category, product], method: :delete, data: { confirm: 'Are you sure?' } %></td> 
    </tr> 
<% end %> 
+1

Danke deine Erklärung macht total Sinn! Die ersten beiden funktionieren perfekt, bis auf die letzte, und es sollte '<% = link_to 'Destroy', [product.category, product], Methode:: delete, data: {confirm: 'Bist du sicher?' }%> 'oder es wird zu ** delete_category_product_path **, das nicht existiert. – jwong

+1

Doh! Bearbeitet, um das zu reflektieren! –

4

ich die problematische Linie bin zu raten, ist eine davon:

<td><%= link_to 'Show', [product, product.category_id] %></td> 
<td><%= link_to 'Edit', [:edit, product, product.category_id] %></td> 

Die product.category_id ist ein Fixnum und das Routing kann nicht wissen, dass eine Zufallszahl soll auf category_id abzubilden.

Verwenden Sie die vorherigen URLs, die Sie hatten, sie sind besser lesbar.

Verwandte Themen