简体   繁体   English

has_many关联中的Rails渴望负载标识符

[英]Rails Eager Load Identifiers in has_many Association

Say I have the following models: 说我有以下模型:

class Category < ActiveRecord::Base
    has_and_belongs_to_many :items
end

class Item < ActiveRecord::Base
    has_and_belongs_to_many :categories
end

I'm building an endpoint that retrieves all items, where each item should be coupled with the array of category IDs it belongs to. 我正在构建一个可以检索所有项目的端点,每个项目都应与其所属的类别ID数组结合在一起。 An example result would be: 结果示例如下:

[
    {
        name: 'My Item',
        category_ids: [1, 2, 3]
    },
    // more items...
]

With this configuration, I'm able to call item.category_ids on each record which results in the SQL that I want, which looks like SELECT categories.id FROM categories INNER JOIN categories_items ... WHERE categories_items.item_id = $1 . 通过这种配置,我可以在每条记录上调用item.category_ids ,从而生成所需的SQL,该SQL看起来像SELECT categories.id FROM categories INNER JOIN categories_items ... WHERE categories_items.item_id = $1 item.category_ids SELECT categories.id FROM categories INNER JOIN categories_items ... WHERE categories_items.item_id = $1

However, that obviously results in an N+1 - and I can't seem to find a way to do this now in an eager load. 但是,这显然会导致N + 1-而且我现在似乎找不到一种方法来解决这个问题。 What I'm looking to do is get a list of items, and just the ID of the categories that they're in, by eager loading the category_ids field of each Item (although, if there's another way to accomplish the same using eager loading I'm okay with that as well) 我正在寻找做的就是项目的列表,以及他们所在的类别只是 ID,通过预先加载的category_ids各领域Item (虽然,如果有另一种方式来完成相同的使用预先加载我也可以)

Edit to explain difference from the duplicate: 编辑以说明与重复项的区别:

I'm looking to see if it's possible to do two this in two separate queries. 我正在寻找是否有可能在两个单独的查询中执行两个操作。 One that fetches items, and one that fetches category IDs. 一种用于获取项目,一种用于获取类别ID。 The items table is relatively wide, I'd prefer not to multiply the number of rows returned by the number of categories each item has - if possible. 项目表相对较宽,如果可能的话,我不希望将返回的行数乘以每个项目具有的类别数。

Using a join model instead of has_and_belongs_to_many will allow you to query the join table directly instead (without hacking out a query yourself): 使用has_and_belongs_to_many模型代替has_and_belongs_to_many将允许您直接查询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

Note that the table naming scheme for has_many through: is different - instead of items_categories its item_categories . 请注意, has_many through:的表命名方案是不同的-代替了items_categoriesitem_categories This is so that the constant lookup will work correctly (otherwise rails looks for Items::Category as the join model!) - so you will need a migration to rename the table. 这样一来,常量查找将可以正常工作(否则,rails将把Items::Category查找为Items::Category模型!)-因此,您将需要进行迁移以重命名表。


items = Item.all
category_ids = ItemCategory.where(item_id: items.ids).pluck(:category_id)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM