1

私はHABTM 関連付けを持っていますPopupUser

Popup次のようなスコープを作成しようとしています。Popup.not_seen_by(current_user).first

残念ながら、以下の私の実装は機能しません。私は正しい道を進んでいるように感じます。この最後のハードルを乗り越えるのを手伝ってくれる人はいますか?

class Popup < ActiveRecord::Base
  has_and_belongs_to_many :users, :uniq => true

  scope :not_seen_by, lambda { |user| 
    # This does NOT work
    joins("LEFT JOIN popups_users ON popups.id = popups_users.popup_id").
    where("popups_users.user_id != ?", user.id)
  }
end

ありがとうございました!

4

1 に答える 1

2

あなたは正しい軌道に乗っていますが、一致する popup_id (つまり、user_id を含まない行) を持つ popups_users のすべての行に参加しているため、同じポップアップの複数のインスタンスを返します。これはあなたが探しているものでなければなりません:

scope :not_seen_by, lambda { |user| where('id NOT IN (select popup_id 
                                                  from popups_users 
                                                  where user_id = ?)',user.id) }

元の「IN」バージョンが機能しなかった理由がよくわかりません。NOT IN は通常かなり遅いので、これも試してみると同等であり、より高速になる可能性があります。

scope :not_seen_by, lambda { |user| where('NOT EXISTS (select 1 
                                                  from popups_users
                                                  where popups_users.popup_id = popups.id
                                                  and user_id = ?)',user.id) }
于 2012-06-07T09:35:06.503 に答える