1

私の User モデル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

だからレールで私はこれを試しました:

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

私は何が欠けていますか?

4

2 に答える 2

2

完成のために:

Rails 3 では、実際には 1 つのクエリだけで問題を解決できましたが、結合を使用することも推奨されています: User.includes(:event_patrons).where("event_patrons.event_id", 1)

出典: 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-最初の完全なチュートリアル パート 2

于 2012-06-28T16:21:06.653 に答える
1

Rails は意図的にそれを行います。次のようにクエリを使用する必要があります。

User.all(:joins => :event_patrons, 
         :conditions => {:event_patrons => {:event_id => 1}}
         :include => :event_patrons)

これにより、2 つのクエリが生成されます。ユーザー向けの 1 つ:

SELECT `users`.* FROM `users` 
INNER JOIN `event_patrons` ON `event_patrons`.`user_id` = `users`.`id` 
WHERE `event_patrons`.`event_id` = 1

関連付けられた event_patrons 用の 1 つ:

SELECT `event_patrons`.* FROM `event_patrons` WHERE `event_patrons`.`id` IN (1,2,3...)

:select オプションを指定することで、やりたいことを実行できますが、event_patrons モデルを構築せず、users モデルにデータを残すため、これはお勧めしません。

于 2012-06-28T15:24:09.967 に答える