有一种方法可以将某些内容置于ActiveRecord的关联表中吗?
我以这种方式检索segments
:
@segments = Segment.all
但是,Segment
has_many
products
。参见:
模型/ product.rb:
class Product < ActiveRecord::Base
belongs_to :segment, dependent: :destroy
end
模型/ segment.rb:
class Segment < ActiveRecord::Base
has_many :products
end
问题是:我只想检索其状态等于1
的产品。我可以使用where
模型上的Segment
来解决这类问题,但我如何才能为products
实现这一目标?
我找到了解决方案。看看:
@segments = Segment.find(:all, include: :products, conditions: {products: {status: 1}})
它有效,但我认为代码可以更好。
那么,如果关联已经存在于模型中,为什么我应该使用include: :products
?我们通过模型关联事物,我确信这已经足够接近。
想法?
答案 0 :(得分:2)
Segment.joins(:products).where("products.status = 1")
您也可以使用包含而不是连接。但是rails会在内部将其转换为连接,因为您在查询中使用了products table属性
答案 1 :(得分:1)
这应该可以胜任 - 它与AREL语法兼容:
@segments = Segment.joins(:products).where(products: {status: 1})
使用include
(或includes
,因为它将是Rails 3/4)的解决方案完全不同,因为它使用INNER JOIN
生成查询,而生成includes
LEFT OUTER JOIN
。此外,includes
通常用于急切加载相关记录,而不是JOIN
的查询。
答案 2 :(得分:1)
一些提示,可能会对您有所帮助。
为了便于命名,我认为status==1
为active
。当然我不知道在你的具体情况下它意味着什么。
class Product
ACTIVE=1
def self.active
where(status: ACTIVE)
end
end
现在你写下这样的话:
segment.products.active
这将仅返回给定段的活动产品。
您找到的解决方案将使用(有效)产品检索所有细分,可以采用不同的方式编写,如下所示:
Segment.includes(:products).where(products: {status: 1})
现在,为什么这么详细:这实际上转换为sql查询,所以你必须对它更加明确。
答案 3 :(得分:1)
如果您只想要状态为1
的人class Segment < ActiveRecord::Base
has_many :products, :conditions => { :status => 1 }
end
在rails 3或
中class Segment < ActiveRecord::Base
has_many :products, -> { where status: 1 }
end
在rails 4中
显然可以使用status:如果它是布尔值,则为true
然后
@segments = Segment.includes(:products)
答案 4 :(得分:1)
has_many:products 关联可以在您的范围内使用 include :: product 。因此,您不应怀疑您的解决方案。这是正确的,它与其他答案中提出的解决方案相同,但是通过其他合成方式。