2012-06-06 52 views
1

我有PopupUser有一个HABTM协会。Rails找到哪里HABTM协会是零

我试图写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 

谢谢!

回答

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) } 
+0

有没有这样做的方式没有子选择?或者是最快的SQL方式呢? –

+0

此外,只是尝试了这一点,它不起作用 –

+0

好吧,我把它改成'where('id NOT IN(select pop_id from popups_users where user_id =?)',user.id)'并且工作。如果您更新了答案,我会将其标记为正确。 –