2011-07-19 89 views
1

你好,我想创建一个查询,是这样的,“给我它具有以下成分的品种(1,2,3)”Rails 3中许多一对多查询

这里有我的模特

class Ingredient < ActiveRecord::Base 
    has_and_belongs_to_many :varieties 

class Variety < ActiveRecord::Base 
    has_and_belongs_to_many :ingredients 

我一直在砸我的脑袋,但是我一直没能弄清楚,请有人帮助我。提前致谢!

回答

3

Dylan评论后更正。为了便于阅读,我将where_clause分解为多行字符串。

ingredient_list = [1,2,3] 
where_clause = %{ 
varieties.id IN 
(SELECT v.variety_id FROM 
(SELECT variety_id, count(*) as cnt FROM ingredients_varieties WHERE ingredient_id in (#{ingredient_list.join(',')}) GROUP BY variety_id) v 
WHERE v.cnt = #{ingredient_list.size}) 
} 
Variety.where(where_clause) 
+0

我觉得这会给你任何'Variety'那至少有一种成分,而我认为他希望它包括所有3种成分。 –

+0

首先谢谢...第一个查询看起来不错,但问题是我需要品种,其中包含完全是这些成分,而不是至少一个 – rogeliog

+0

编辑回答问题 –

1

不知道性能(我们不知道优化过早),但是这绝对是比纯SQL更具可读性:

@ingredients = Ingredient.includes(:varieties).find [1,2,3] 
@varieties = @ingredients.collect(&:varieties).inject(&:&).reject{|v| v.ingredients.size != @ingredients.size} 
+0

嘿,RocketR实际上工作真的很好,但问题是如果它至少包含(1,2,3)成分,它就会获得多样性。但是,如果该品种还包括(4)成分,它也可以得到它,我只有在包含完全(1,2,3)成分时才需要获得该品种,不过谢谢任何方式 – rogeliog

+0

@rogeliog我更新了代码以拒绝品种超过3种成分。 – RocketR