关联条件Rails 4

时间:2014-03-20 14:16:06

标签: ruby-on-rails activerecord

有一种方法可以将某些内容置于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?我们通过模型关联事物,我确信这已经足够接近。

想法?

5 个答案:

答案 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==1active。当然我不知道在你的具体情况下它意味着什么。

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 。因此,您不应怀疑您的解决方案。这是正确的,它与其他答案中提出的解决方案相同,但是通过其他合成方式。