【问题标题】:ActiveRecord association returns "NoMethodError for ActiveRecord::Relation"ActiveRecord 关联返回“NoMethodError for ActiveRecord::Relation”
【发布时间】:2013-03-13 21:22:09
【问题描述】:

我有 3 个具有“1 到 n”关联的模型,像这样

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

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

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

我越来越对 ActiveRecord 关联的东西感到困惑

在我的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 对象,但我找不到从这里继续并获取链接到此类别列表的项目列表的方法。

我也开始提取第一行返回的类别ID列表,以便在第二行的where子句中使用它们,但是在编写代码时我发现它不优雅,并认为可能有更好的方法去做吧。任何帮助将不胜感激。谢谢

models/client.rb

class Client < ActiveRecord::Base
  has_many :categories
  has_many :items, through: :categories
  ...
end

models/category.rb

class Category < ActiveRecord::Base
  belongs_to :client
  has_many :items
  ...
end

model/item.rb

class Item < ActiveRecord::Base
  belongs_to :category
  has_one :client, through: :category
  ...
end

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    您只能在类别对象上调用.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 中的内容感兴趣,那么最好使用joins 在一个查询而不是两个查询中进行:

    @items = Item.joins(:category)
        .where('items.name LIKE ? AND categories.name = ? AND categories.client_id = 2', "%#{params[:filter_items]}%", "%#{params[:filter_categories]}%")
    

    【讨论】:

    • 对不起,你不是说categories.first.items吗?
    【解决方案2】:

    你可以这样试试:

    item_ids = Client.find(2).categories.inject([]) { |ids, cat| ids |= cat.item_ids; ids }
    items = Item.find(item_ids)
    

    这样您就可以获得通过另一个表关联的嵌套对象列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 2013-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多