我的用户模型has_many :event_patrons
和EventPatron belongs_to :user
。我想用一个特定的事件赞助人将用户与这个sql语句:
SELECT * FROM `users`
INNER JOIN `event_patrons` ON `event_patrons`.`user_id` = `users`.`id`
WHERE `event_patrons`.`event_id` = 1
所以在rails中我尝试了这个:
User.all(:joins => :event_patrons,
:conditions => {:event_patrons => {:event_id => 1}})
但这给了我SELECT users.*
而不是SELECT *
:
SELECT `users`* FROM `users`
INNER JOIN `event_patrons` ON `event_patrons`.`user_id` = `users`.`id`
WHERE `event_patrons`.`event_id` = 1
然后,我尝试将:joins
与:include
切换,并且整个混乱仍然只返回User
中的列,而EventPatron
中没有。
我错过了什么?
答案 0 :(得分:2)
为了完成起见:
在rails 3中,您实际上只能使用一个查询,但他们也建议使用连接: User.includes(:event_patrons).where(“event_patrons.event_id”,1)
来源:Specifying Conditions on Eager Loaded Associations
我对连接感到困惑,也包括在开头,但是有一个很大的区别:
include基本上是对协会的热切加载。当你要做这样的事情时,这很有用:
@users.each do |user|
user.event_patrons.first.event_id
end
如果您有100个用户,那么您只需生成100个额外查询(1 + N问题)。
有时您需要在关联上指定条件(就像您的情况一样),这是连接有用的地方,但不要过度滥用它,否则您将遇到笛卡尔积过载问题
关于这一切的一篇很棒的文章:可以在这里找到,可能适用于rails 2.1,但仍适用于Rails 3:http://akitaonrails.com/2008/05/25/rolling-with-rails-2-1-the-first-full-tutorial-part-2
答案 1 :(得分:1)
Rails故意这样做。你应该使用这样的查询:
User.all(:joins => :event_patrons,
:conditions => {:event_patrons => {:event_id => 1}}
:include => :event_patrons)
这将生成2个查询。一个用户:
SELECT `users`.* FROM `users`
INNER JOIN `event_patrons` ON `event_patrons`.`user_id` = `users`.`id`
WHERE `event_patrons`.`event_id` = 1
一个用于关联的event_patrons:
SELECT `event_patrons`.* FROM `event_patrons` WHERE `event_patrons`.`id` IN (1,2,3...)
你可以通过指定:select选项来做你想要的,但我不建议这样做,因为它不构造event_patrons模型,它将数据保留在用户模型中。