2014-10-05 56 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