In my Sinatra
app my model defines a HABTM relationship between Users
and Notifications
. I am trying to define a couple of scopes, one for all Notifications
associated with no Users
called unread
and one that returns all Notifications
that are 'unread' by a particular User
.
class Notification < ActiveRecord::Base
has_and_belongs_to_many :users
scope :unread, ->{
Notification.joins("LEFT JOIN notifications_users ON notifications.id = notifications_users.notification_id").
where("notifications_users.user_id IS NULL").uniq
}
scope :unread_by, ->(u){
Notification.joins("LEFT JOIN notifications_users ON notifications.id = notifications_users.notification_id").
where("notifications_users.user_id <> ?", u.id).uniq
}
The unread
scope works fine but the unread_by
scope is not giving me the results I expect.
it "should know which notifications have not yet been read by anyone, or by a particular user" do
n1 = Notification.create!(title: 'test 1', text: 'this is some longer text about the notification')
n2 = Notification.create!(title: 'test 2', text: 'this is also some longer text about the notification')
Notification.unread.must_include(n1)
Notification.unread.must_include(n2)
@user1.read(n1)
Notification.unread.wont_include(n1)
Notification.unread.must_include(n2)
Notification.unread_by(@user1).wont_include(n1)
Notification.unread_by(@user1).must_include(n2) # => fails
Notification.unread_by(@user2).must_include(n1)
Notification.unread_by(@user2).must_include(n2) # => fails
end
I suspect my query logic is flawed but I've been staring at this for too long and I'm just not seeing it. What am I missing?
Okay this fixed it, but it doesn't seem super-elegant to me.
It works though. Yay - Thanks all for your help, it pointed me in the right direction.