ActiveRecord关联返回“ActiveRecord :: Relation的NoMethodError”

时间:2013-03-13 12:53:52

标签: ruby-on-rails

我有3个带有“1到n”关联的模型,比如这个

Client --1到n - > Category --1到n - > Item

在一个页面中,我需要显示项目列表及其类别。此页面需要进行3级过滤:

  • 客户端过滤:我知道客户端ID(在此示例中我将使用'id = 2')
  • 类别名称:用户设置的动态过滤器
  • 项目名称:用户设置的动态过滤器

我对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

2 个答案:

答案 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)

这是如何获取通过另一个表关联的嵌套对象列表。

相关问题