1

我有Popup一个UserHABTM 协会。

我正在尝试为此编写一个范围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

您在正确的轨道上,但是您正在加入 popups_users 中具有匹配 popup_id 的每一行(即不包含您的 user_id 的行),因此返回同一弹出窗口的多个实例。这应该是您正在寻找的:

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 回答