2016-01-26 97 views
2

我有BikeCategory型號。自行車has_many類別通過BikeFilter模型。使用關聯的過濾器邏輯

問題是,從搜索我得到讓我們說5個不同的類別,我只需要找到這些自行車,其中所有5個這些類別記錄在BikeFilter表。

如果我在mysql中執行GROUP BY,它還會選擇記錄,其中bike_filters中只有1個或幾個類別的記錄。並且需要誰擁有他們全部。

Bike.rb

has_many :bike_filters 
has_many :categories, :through => :bike_filters 

BikeFilter.rb

belongs_to :category 
belongs_to :bike 

回答

3

您可以使用having條款: http://guides.rubyonrails.org/active_record_querying.html#having

,並做類似如下:

Bike.select("bikes.*, count(*) as num_of_categories") 
    .joins(:categories) 
    .where(categories: { id: cats }) 
    .group("bikes.id") 
    .having("num_of_categories = ?", cats.length) 

此查詢將首先執行自行車和類別之間的Inner Join(通過BikeFilter表格),然後它將只選​​擇cats陣列中包含category_id的行。 在這一點上,查詢將根據自行車ID對所有記錄進行分組,並只返回行數等於分類數的組。

夫婦的注意事項:

  • 如果(bike_id,CATEGORY_ID)對處於BikeFilter表中是唯一這樣纔有效。
  • 該查詢將返回與所有給定類別相關的所有自行車,而不管它們是否具有與其相關的其他類別。
+0

但是,如果'貓'包含例如5個類別,這不僅交付那些**全部5 **類別的自行車。您還可以獲得5類自行車,其中只有一類屬於「貓」。 – tillmo

+0

@tillmo - 我不這麼認爲 - 只過濾cats中的category id行(where子句)過濾所有的行,所以剩下的只剩下行是'cats'中的category,所以其他類不會被計算在內在'count(*)'上,因此不予考慮。 – Dani

+0

你是對的。但是,'> ='與'='沒有區別。在這兩種情況下,都會返回包含指定類別的所有自行車。這是因爲'where(categories:{id:cats})'已經限制計數到指定的類別。 – tillmo