2013-01-20 64 views
1

我有這個關係的關係在我Product模型:過濾Rails中

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

所以我可以做Product.features

工作正常。但是我希望能夠在需要時根據feature表中的字段進行過濾。例如,在僞碼:

find all product features where feature is comparable 

compare是在feature一個bool字段。

我一直試圖堅持2個小時,並且無法弄清楚(無需完全寫入新的查詢)。我不知道如何訪問Product.features關係中feature表的字段,因爲它似乎只能在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 

我希望能夠查詢屬於一個productfeature其中Feature.comparetrueproduct_features。事情是這樣的:

product.rb

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

這將引發在Feature模式,而不是ProductFeature一個錯誤,因爲compare。我在product_feature.rb中嘗試過以下內容:

delegate :compare, :to => :feature 

但我沒有幫助。

我會在幾個小時內爲此添加賞金,所以請幫助我!

+0

我很困惑應用程序的組織。因此,您有一個功能表和一個product_features表,以及一個功能模型和一個ProductFeature模型? –

+0

另外,你不需要:source屬性,因爲'has_many:features'不是'has_many:through'關聯。 –

+0

我開始懷疑你需要':include =>:feature'部分,除非ProductFeature有一個特性。 –

回答

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的範圍內。

+0

有沒有辦法直接對產品的product_features關係做過濾呢? IE product_features.where(:features => {:compare => true})? –

+0

當然可以,但你需要先加入。所以'some_product.product_features.joins(:features).where(:features => {:compare => true})''。這就是我在答案中所做的一切「some_product」示例,只是它隱藏了範圍中的細節。 – 2013-01-23 11:26:47

+0

好吧,如果我已將ProductFeature設置爲包含:feature,我還需要加入嗎? –

1

這看起來像一個has_many:通過關係。嘗試改變這一點:

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相應的列(產品,FEATURE_ID) ,那麼您應該可以訪問該產品的功能以及Product和ProductFeature上的所有屬性。

在這裏看到:

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

編輯:這裏是如何通過功能領域進行篩選。

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

嗯。但是,這隻會說:未知列'product_features.compare' –

+0

你嘗試了@MattHumphrey,還是隻是猜測? – hd1

+0

不應該說,如果您已經編寫了用於添加比較字段並運行它的product_features的遷移。 –

0

@product.each |p| { p.features.where(:comparable => true) }可能是你最好的選擇,但我很樂於被開悟。

+0

我已經更新了模型方面的問題@ hd1 –