Ruby on rails 筛选Rails中的关系

Ruby on rails 筛选Rails中的关系,ruby-on-rails,ruby,ruby-on-rails-3,arel,Ruby On Rails,Ruby,Ruby On Rails 3,Arel,我在我的产品型号中有这种关系: has_many :features, :class_name => 'ProductFeature', :source => :product_feature, :include => :feature 所以我可以做Product.features 这很好用。但我希望能够在必要时通过功能表中的字段对其进行过滤。例如,在伪代码中: find all product features where feature is comparable co

我在我的
产品
型号中有这种关系:

has_many :features, :class_name => 'ProductFeature', :source => :product_feature, :include => :feature
所以我可以做
Product.features

这很好用。但我希望能够在必要时通过
功能表中的字段对其进行过滤。例如,在伪代码中:

find all product features where feature is comparable
compare
功能上的布尔字段

我已经尝试了2个小时,但无法理解(如果不完全编写新的查询)。我不知道如何从
Product.features
关系中访问
feature
表的字段,因为它似乎只能过滤
Product\u features
字段

这就是我到目前为止的想法:

def features_compare
  features.feature.where(:compare => true)
end
但它只是说,
功能
不是一种有效的方法,我理解这一点

编辑 我已经更新了我的模型,因此关系更加清晰:

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
delegate :compare, :to => :feature
但我没有帮忙


我会在几个小时内增加一笔赏金,所以请帮帮我

这似乎有很多:通过关系。尝试更改此选项:

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上的所有属性

请看这里:

编辑:以下是如何按要素字段过滤

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

@product.each | p |{p.features.where(:comparable=>true)}
可能是您在这里的最佳选择,但我愿意接受启发。

查找所有功能可比的产品功能

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

Hmmm上把它变成一个作用域。但那只会说:未知列“Product\u features.compare”你试过了吗,@MattHumphrey,还是你只是在猜测?它不应该说如果你已经为Product\u features编写了迁移,添加了比较字段并运行它。不,我试过,我知道为什么。这个关系,features,实际上是一个product_features关系。我已经用模型上下文@JoshuaRiekenI更新了这个问题,我对应用程序的组织感到困惑。所以你有一个功能表和一个产品功能表,还有一个功能模型和一个产品功能模型,你不需要:source属性,因为
有很多:功能
不是
有很多:通过
关联。我开始怀疑你是否也需要
:include=>:feature
部分,除非ProductFeature有一个功能。我可以看到你的情况!我有一个功能模型,其中包含一组功能,如“颜色”、“大小”、“形状”等。然后是一个ProductFeature模型,其中包含指向产品和功能的链接,并包含一个“值”,如“黑色”、“中等”,“round”等。为了更好的可读性,我在产品模型中将关系重命名为“features”,而不是“product_features”(我希望是lol)。我需要包含,以便我可以通过关系访问功能名称。那么,没有办法直接对product_features关系进行过滤吗?IE product_features.where(:features=>{:compare=>true})?当然可以,但您需要先加入。所以
some\u product.product\u features.join(:features).where(:features=>{:compare=>true})
。这就是我的
答案中的一些产品
示例所做的,只是它隐藏了范围中的详细信息。好的,如果我将ProductFeature设置为includes:feature,我还需要加入吗?(顺便说一句,我刚刚编辑了我的答案,使用
:feature
,而不是
:features
。我忘记了每个产品功能只有一个功能。)当你说“包括”时,你是指代表吗?是的,所有学员所做的就是将对
product\u功能的调用。比较
转换为
product\u功能。功能。比较
。它根本不会影响查询。考虑这一切的一种方法是注意,如果
委托
确实影响了查询,那么它必须偷偷地写一个连接,因为相关数据位于不同的表中。它可以做但不能做的另一件事是将字段复制/更新到
product\u features
表中的一个额外列中。实际上,您可以通过一点工作(或gem)来实现这种非规范化,有些情况需要这样做。但除非你有迫切的理由这么做,否则我还是坚持自己加入。这当然是最简单的解决办法。
#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})