我有3个带有“1到n”关联的模型,比如这个
Client
--1到n - > Category
--1到n - > Item
在一个页面中,我需要显示项目列表及其类别。此页面需要进行3级过滤:
我对ActiveRecord Associations的内容越来越感到困惑
在我的ItemsController#index
中,我尝试了这个:
categories = Client.find(2).categories
.where('name LIKE ?', "%#{params[:filter_categories]}%")
@items = categories.items
.where('name LIKE ?', "%#{params[:filter_items]}%")
第二行引发NoMethodError undefined method 'items' for ActiveRecord::Relation
。我知道第一行返回一个Relation对象,但我找不到从这里继续的方法,并获得链接到这个类别列表的Items列表。
我也开始提取第一行返回的类别ID列表,以便在第二行的where子句中使用它们,但在编写代码时我发现它不够优雅,并认为可能有更好的方法去做吧。任何帮助将非常感激。感谢
模型/ client.rb
class Client < ActiveRecord::Base
has_many :categories
has_many :items, through: :categories
...
end
模型/ category.rb
class Category < ActiveRecord::Base
belongs_to :client
has_many :items
...
end
模型/ item.rb的
class Item < ActiveRecord::Base
belongs_to :category
has_one :client, through: :category
...
end
答案 0 :(得分:2)
您只能在类别对象上调用.items
,而不能在集合上调用@items = categories.first.items
.where('name LIKE ?', "%#{params[:filter_items]}%")
。这个将工作:
@items = Item
.where('category_id IN (?) AND name LIKE ?', categories, "%#{params[:filter_items]}%")
要获得所需内容,您可以执行以下操作:
@items
假设最后您只对@items = Item.joins(:category)
.where('items.name LIKE ? AND categories.name = ? AND categories.client_id = 2', "%#{params[:filter_items]}%", "%#{params[:filter_categories]}%")
中的内容感兴趣,那么使用joins
在一个查询而不是两个查询中做得更好:
{{1}}
答案 1 :(得分:0)
你可以尝试这样的smth:
item_ids = Client.find(2).categories.inject([]) { |ids, cat| ids |= cat.item_ids; ids }
items = Item.find(item_ids)
这是如何获取通过另一个表关联的嵌套对象列表。