假设我有一个Item
模型和Category
模型与has_many :through
关联:
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
现在,我希望在项目上有一个范围,它将获取特定类别的所有项目(假设它具有状态属性)。例如:获取状态为“库存”且属于id = 3的类别的所有项目,例如:
scope :in_stock_for_category, ->(category) { where(status: SOME_ENUMERATED_VALUE) ....
我错过了查询的最后一部分,将结果集限制为特定类别。
谢谢!
答案 0 :(得分:1)
由于您的category_id
表格中没有items
列,因此您需要加入范围中的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
那应该整理一下。