1

我的用户模型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

然后,我尝试切换:joinswith:include并得到一团乱麻,仍然只返回我的列,User而没有 from EventPatron

我错过了什么?

4

2 回答 2

2

为了完成:

在 Rails 3 中,您实际上可以只使用一个查询,但他们也建议使用连接: User.includes(:event_patrons).where("event_patrons.event_id", 1)

来源:在急切加载的关联上指定条件

我在开始时也对连接和包含感到困惑,但有很大的不同:

  • 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-第一个完整教程第 2 部分

于 2012-06-28T16:21:06.653 回答
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 模型,而是将数据留在用户模型中。

于 2012-06-28T15:24:09.967 回答