Rails - 预加载 has_many :通过关联条件
Rails - eager load has_many :through with condition on association
假设我有一个 Item
模型和具有 has_many :through
关联的 Category
模型:
class Item < ActiveRecord::Base
has_many :category_items
has_many :categories, through: category_items
end
class Category < ActiveRecord::Base
has_many :category_items
has_many :items, through: category_items
end
class CategoryItems < ActiveRecord::Base
belongs_to :category
belongs_to :items
end
现在,我想要一个项目范围,它将获得特定类别的所有处于特定状态(假设它具有状态属性)的项目。例如:获取所有状态为 "in stock" 且属于 id = 3 类别的项目,例如:
scope :in_stock_for_category, ->(category) { where(status: SOME_ENUMERATED_VALUE) ....
我遗漏了将结果集限制为特定类别的查询的最后一部分。
谢谢!
由于您的 items
table 中没有 category_id
列,您需要在范围中加入 category_items
或 cateogeries
在指定特定类别的 ID 条件之前。
class Item < ActiveRecord::Base
scope :in_stock_for_category, -> do |category|
joins(:category_items).
where(category_items: {category_id: category.id}).
where(items: {status: SOME_ENUMERATED_VALUE}).
group("items.id") # grouping might be unnecessary since you're adding the where condition for the category's id
end
end
那行得通。或者,如果您想加入 categories
,请执行以下操作:
class Item < ActiveRecord::Base
scope :in_stock_for_category, -> do |category|
joins(:categories).
where(categories: {id: category.id}).
where(items: {status: SOME_ENUMERATED_VALUE}).
group("items.id") # grouping might be unnecessary since you're adding the where condition for the category's id
end
end
但是,如果您已经拥有 category
,则为具有特定状态的项目创建 has_many
关系可能会很有用。类似于以下内容:
class Category < ActiveRecord::Base
has_many :in_stock_items, -> do
where(items: {status: SOME_ENUMERATED_VALUE})
end, through: :category_items, source: :item
end
此外,如果您在 Item
中有状态范围(类似于 scope :in_stock, -> { where(status: SOME_ENUMERATED_VALUE) }
),您很可能可以将上述 has_many
关系更改为以下内容:
class Category < ActiveRecord::Base
has_many :in_stock_items, -> do
merge(Item.in_stock) # http://apidock.com/rails/ActiveRecord/SpawnMethods/merge
end, through: :category_items, source: :item
end
那应该收拾东西了。
假设我有一个 Item
模型和具有 has_many :through
关联的 Category
模型:
class Item < ActiveRecord::Base
has_many :category_items
has_many :categories, through: category_items
end
class Category < ActiveRecord::Base
has_many :category_items
has_many :items, through: category_items
end
class CategoryItems < ActiveRecord::Base
belongs_to :category
belongs_to :items
end
现在,我想要一个项目范围,它将获得特定类别的所有处于特定状态(假设它具有状态属性)的项目。例如:获取所有状态为 "in stock" 且属于 id = 3 类别的项目,例如:
scope :in_stock_for_category, ->(category) { where(status: SOME_ENUMERATED_VALUE) ....
我遗漏了将结果集限制为特定类别的查询的最后一部分。
谢谢!
由于您的 items
table 中没有 category_id
列,您需要在范围中加入 category_items
或 cateogeries
在指定特定类别的 ID 条件之前。
class Item < ActiveRecord::Base
scope :in_stock_for_category, -> do |category|
joins(:category_items).
where(category_items: {category_id: category.id}).
where(items: {status: SOME_ENUMERATED_VALUE}).
group("items.id") # grouping might be unnecessary since you're adding the where condition for the category's id
end
end
那行得通。或者,如果您想加入 categories
,请执行以下操作:
class Item < ActiveRecord::Base
scope :in_stock_for_category, -> do |category|
joins(:categories).
where(categories: {id: category.id}).
where(items: {status: SOME_ENUMERATED_VALUE}).
group("items.id") # grouping might be unnecessary since you're adding the where condition for the category's id
end
end
但是,如果您已经拥有 category
,则为具有特定状态的项目创建 has_many
关系可能会很有用。类似于以下内容:
class Category < ActiveRecord::Base
has_many :in_stock_items, -> do
where(items: {status: SOME_ENUMERATED_VALUE})
end, through: :category_items, source: :item
end
此外,如果您在 Item
中有状态范围(类似于 scope :in_stock, -> { where(status: SOME_ENUMERATED_VALUE) }
),您很可能可以将上述 has_many
关系更改为以下内容:
class Category < ActiveRecord::Base
has_many :in_stock_items, -> do
merge(Item.in_stock) # http://apidock.com/rails/ActiveRecord/SpawnMethods/merge
end, through: :category_items, source: :item
end
那应该收拾东西了。