2014-10-05 47 views
0

我有兩個模型產品和類別。檢索導軌關聯的反向多個記錄

我能做出這樣Category.products等

成功查詢Product.rb

belongs_to :category 

Category.rb

has_many :products 

現在我想找回只有那些至少有一個現有產品的類別。

我想是這樣的:

@categories = Category.where(Category.products.present?) 

#返回的錯誤未定義的方法`產品也改變產品沒有工作。

回答

1

讓您的評論,你需要的產品和該產品類別物業with_operator是真實的,你可以使用joinsmerge做「軌道式」該查詢:

@categories = Category.joins(:products).merge(Product.where(with_operator: true)).uniq 

這將生成的SQL語句:

SELECT DISTINCT "categories".* FROM "categories" INNER JOIN "products" ON "products"."category_id" = "categories"."id" WHERE "products"."with_operator" = 't' 

你也可以用鋼軌4語法,通過@yukke如指出:

Category.joins(:products).where(products: { with_operator: true }).uniq 
+0

Rails合併不會生成SQL UNION運算符。你的代碼等於next:Category.joins(:products).where(with_operator:true).uniq – 2014-10-06 14:40:00

+0

而不是合併的意圖(閱讀文檔)。合併是告訴rails'with_operator'是產品表的條件,而不是類別表的條件。 – lcguida 2014-10-06 16:42:47

+0

如果您運行'Category.joins(:products).where(with_operator:true).uniq'將返回一個錯誤,因爲rails會認爲'with_operator'是類別表 – lcguida 2014-10-06 18:01:42

1

所有你需要的是內部連接。它會跳過那些沒有產品的類別。並增加在連接表的條件,你可以使用軌道4中的語法:

@categories = Category.joins(:products).where(products: { with_operator: true }).uniq 

它會產生下一個SQL查詢:

SELECT DISTINCT "categories".* 
FROM "categories" INNER JOIN "products" ON "products"."category_id" = "categories"."id" 
WHERE "products"."with_operator" = 't' 
+0

他爲什麼會需要to_a? – lcguida 2014-10-05 16:35:14

+0

to_a顯式運行sql查詢並將ActiveRecord :: Relation轉換爲Array。當然,他可以跳過它,這只是良好的習慣和習慣。 – 2014-10-05 16:44:49

+0

@yukke看起來不錯,Tnx – Edgars 2014-10-05 16:58:16