过滤Rails中的关系

时间:2013-01-20 23:11:55

标签: ruby-on-rails ruby ruby-on-rails-3 arel

我在Product模型中有这种关系:

has_many :features, :class_name => 'ProductFeature', :source => :product_feature, :include => :feature

所以我可以做Product.features

工作正常。但是我希望能够在必要时根据feature表中的字段对其进行过滤。例如,在伪代码中:

find all product features where feature is comparable

comparefeature上的bool字段。

我已经尝试了2个小时,并且无法弄清楚(没有完全编写新查询)。我无法弄清楚如何从feature关系访问Product.features表的字段,因为它似乎只能过滤product_features个字段。

这是我到目前为止所提出的:

def features_compare
  features.feature.where(:compare => true)
end

但它只是说feature不是一种有效的方法,我理解。

修改

我已更新我的模型,因此关系更清晰:

product.rb:

class Product < ActiveRecord::Base
  belongs_to :company
  belongs_to :insurance_type

  has_many :product_features
  has_many :reviews

  attr_accessible :description, :name, :company
end

product_feature.rb:

class ProductFeature < ActiveRecord::Base
  belongs_to :product
  belongs_to :feature

  delegate :name, :to => :feature

  attr_accessible :value
end

feature.rb

class Feature < ActiveRecord::Base
  attr_accessible :name, :compare
end

我希望能够查询属于product_features的{​​{1}}和product feature Feature.compare true。像这样:

product.rb

def features_compare
  product_features.where(:compare => true)
end

这会引发错误,因为compare模型中有Feature,而不是ProductFeature。我在product_feature.rb中尝试了以下内容:

delegate :compare, :to => :feature

但我没有帮助。

我会在几个小时内为此添加赏金,所以请帮助我!

3 个答案:

答案 0 :(得分:2)

find all product features where feature is comparable只是

ProductFeature.joins(:feature).where(:feature => {:compare => true})

通过引入范围,您可以使其更具可重用性:

#in product_feature.rb
scope :with_feature_like, lambda do |filter|
   joins(:feature).where(:feature => filter)
end

#elsewhere
ProductFeature.with_feature_like(:compare => true)

#all the product features of a certain product with at comparable features
some_product.product_features.with_feature_like(:compare => true)

最后,如果您希望所有具有相似功能的产品功能的产品,您需要以下内容:

Product.joins(:product_features => :feature).where(:feature => {:compare => true})

当然,您也可以在Product上转换为范围。

答案 1 :(得分:1)

这似乎是一个很好的:通过关系。尝试更改此内容:

has_many :features, :class_name => 'ProductFeature', :source => :product_feature, :include => :feature

到此:

has_many :product_features
has_many :features, :through => :product_features

只要您的ProductFeature模型具有以下内容:

belongs_to :product
belongs_to :feature

您在product_features(product_id,feature_id)上有适当的列,那么您应该能够访问该产品的功能以及Product和ProductFeature上的所有属性。

见这里:

http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association

编辑:以下是按功能字段过滤的方法。

Product.joins(:features).where(:features => {:name => "Size"})

答案 2 :(得分:0)

@product.each |p| { p.features.where(:comparable => true) }可能是你最好的选择,但我愿意受到启发。