我的应用程序有两个型号Category和Product
产品属于类别。
我创建了一个导航栏下拉列表,要求@category和@product对象在整个应用程序中可用(导航栏显示在应用程序的每个页面上。)
我可以解决的问题是放置这些基本定义的最佳位置,而不是在每个页面定义中多次定义它们。
我需要定义以下内容:
@category = Category.all
@products = @category.products.all
导航栏循环将看起来像这样。
<% @category.each do |c| %>
<%= c.name %>
<% @products.each do |p| %>
<% link_to product_path(p) do %>
<%= p.name %>
<% end %>
<% end %>
<% end %>
我是一个铁杆新手,所以我相信这里有一些错误,但任何帮助都会非常感激!
答案 0 :(得分:5)
如果您在应用的每个页面中都需要它们,可以在ApplicationController
before_filter
中设置它们:
class ApplicationController
before_filter :get_categories
# ...
private
def get_categories
@categories = Category.includes(:products)
end
end
然后,你可以写在你的观点中:
<% @categories.each do |category| %>
<%= category.name %>
<% category.products.each do |product| %>
<%= link_to p.name, p %>
<% end %>
<% end %>
我还修复了一些其他错误和常规不兼容问题。
答案 1 :(得分:1)
以下代码不正确。
@category = Category.all
@products = @category.products.all
此代码将@categories
分配给所有类别,然后尝试获取产品。除非您在Category模型中定义了products
类方法,否则它将无法工作。但我不这么认为,否则你只需要致电Product.all
。
此外,在下面的代码中,您尝试显示每个类别的产品列表,这绝对不适用于之前的两个分配。根据您要实现的目标,您无法预先指定@products
,因为您希望将产品用于特定类别。
让我们在代码中内嵌所有内容。
<% Category.all.each do |category| %>
<%= category.name %>
<% category.products.each do |product| %>
<%= link_to product_path(product) do %>
<%= product.name %>
<% end %>
<% end %>
<% end %>
下一步是让代码更高效,让你无处不在。
<% Category.select(:id, :name).each do |category| %>
<%= category.name %>
<% category.products.select(:id, :name).each do |product| %>
<%= link_to product_path(product) do %>
<%= product.name %>
<% end %>
<% end %>
<% end %>
您可以使用pluck
,但它会返回一个数组,并且需要更多操作。但是,它的性能更高。
<% Category.pluck(:id, :name).each do |category_id, category_name| %>
<%= category_name %>
<% Product.where(category_id: category_id).pluck(:id, :name).each do |product_id, product_name| %>
<%= link_to product_name, product_path(id: product_id) %>
<% end %>
<% end %>
在视图中链接所有这些方法并不是一个好主意,让我们将一些代码提取到模型中。
class Category
def self.simple_listing
order(:name).pluck(:id, :name)
end
end
class Product
def self.simple_category_listing(category_id)
where(category_id: category_id).order(:name).pluck(:id, :name)
end
end
<% Category.simple_listing.each do |category_id, category_name| %>
<%= category_name %>
<% Product.simple_category_listing(category_id).each do |product_id, product_name| %>
<%= link_to product_name, product_path(id: product_id) %>
<% end %>
<% end %>
您可以将所有这些代码留在视图中,或将其提取为部分代码。您甚至不需要在过滤之前添加控制器,也不需要将其设置为“全局”。代码是自包含的,不会使用实例变量污染名称空间,并且可以在需要时轻松放置。