说我有以下型号:
class Category < ActiveRecord::Base
has_and_belongs_to_many :items
end
class Item < ActiveRecord::Base
has_and_belongs_to_many :categories
end
我正在构建一个端点,用于检索所有项目,其中每个项目应与其所属的类别ID数组相关联。示例结果将是:
[
{
name: 'My Item',
category_ids: [1, 2, 3]
},
// more items...
]
通过这种配置,我可以在每条记录上调用item.category_ids
,从而产生我想要的SQL,看起来像SELECT categories.id FROM categories INNER JOIN categories_items ... WHERE categories_items.item_id = $1
。
然而,这显然会导致N + 1 - 而且我似乎无法在急切的负载中找到一种方法来做到这一点。我想要做的是获取一个项目列表,只是他们所在类别的ID,急切加载每个category_ids
字段Item
(但是,如果有另一种方法可以使用急切加载来完成相同的操作,我也可以使用它)
编辑以解释与副本的区别:
我正在寻找是否可以在两个单独的查询中执行两个操作。一个获取项目,一个获取类别ID。 items表相对较宽,我不希望将每个项目所包含的类别数返回的行数相乘 - 如果可能的话。
答案 0 :(得分:1)
使用连接模型而不是has_and_belongs_to_many
将允许您直接查询连接表(无需自己破解查询):
class Category < ActiveRecord::Base
has_many :item_categories
has_many :items, through: :item_categories
end
class Item < ActiveRecord::Base
has_many :item_categories
has_many :categories, through: :item_categories
end
class ItemCategory
belongs_to :item
belongs_to :category
end
请注意,has_many through:
的表格命名方案不同 - 而不是items_categories
其item_categories
。这样,常量查找将正常工作(否则rails会查找Items::Category
作为连接模型!) - 因此您需要迁移才能重命名该表。
items = Item.all
category_ids = ItemCategory.where(item_id: items.ids).pluck(:category_id)