I am trying to create a view where I can see all products that belong
to a certain category.
My models have the following relationships:
Category: has_many :products
Product: belongs_to :category
Both category_controller.rb and product_controller.rb are in my admin
area and need Admin login to edit/delete...
I am also using a catalog_controller.rb to view all my products.
In my catalog_controller.rb I created the following:
So, If I go to /catalog/categories, I can see a list of links to all
my categories.
My views/catalog/categories.rhtml has this code:
<ul id="categories">
<% for category in @categories %>
<li><%= link_to category.name, :action =>
"products_by_category", :id => category %></li>
<% end %>
</ul>
My views/catalog/products_by_category.rhtml has this code:
<% if category.products? %>
<p>No Products found for this category</p>
<% else %>
<ul id="products">
<% for product in @products %>
<li><%= link_to product.title, :action => "show", :id => product %></
<% end %>
</ul>
<% end>
But when I click on the category link, I get a NoMethodError in
CatalogController#products_by_category:
undefined method `products' for Category:Class
Method missing
app/controllers/catalog_controller.rb:41:in `products_by_category'
What am I doing wrong?
Would you recommend a better way of achieving this?
btw, the reason that Category.products didn’t work is because the
has_many association adds an instance method to the Category model, not
a class method, so Category.products is not a method, but c =
Category.find(:first); c.products is.
Thanks William. The first solution didn't work. And when I try the
second one like this:
<% if category.products? %>
<p>No Products found for this category</p>
<% else %>
<ul id="products">
<% @category.products.each do |product| %>
<li><% product %></li>
<% end %>
</ul>
<% end %>
I get a NameError:
undefined local variable or method `category' for #<#<Class:0x3260810>:
0x3260748>
Extracted source (around line #1)...
It's hard to say without seeing your full controller method, and your
category / product models and your database data. Try using
script/console to play around with the relationships and debug it there.
Try:
/script/console
then:
c = Category.find(1) #(or whatever category id you are looking at now)
then:
c.products
None-the-less, playing with it in script/console will help you narrow it
down, and if it works as expected there, the problem must be in your
controller and / or view code somewhere.
You *can* do that, but I don't advise it. I think the code is easier to
deal with when all queries are executed in the controller, and all the
view does is render things that the controller has set up. It certainly
makes your code easier to test, since you can check assigns(:products)
in the test method.
Could I ask (what might be a silly question) how would you run the
query in the controller? and how would I change my code in my view?