Rails activerecord包括。如何访问包含的列?

时间:2012-06-28 15:14:28

标签: ruby-on-rails activerecord

我的用户模型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中没有。

我错过了什么?

2 个答案:

答案 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模型,它将数据保留在用户模型中。