0

Sinatra app에 내 모델은 UsersNotifications 사이의 HABTM 관계를 정의합니다. 몇 가지 범위를 정의하려고합니다. 하나는 unread이라는 Users과 연결된 Notifications이고 다른 하나는 User으로 '읽지 않음'인 모든 Notifications을 반환하는 스코프입니다.매개 변수가있는 스코프 및 ActiveRecord (Ruby)와의 has_and_belongs_to_many 연관

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 
    } 

unread 범위는 잘 작동하지만 unread_by 범위는 나에게 내가 기대하는 결과를 제공하지 않습니다.

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 

나는 내 쿼리 논리가 결함이 의심하지만 난 너무 오랫동안이 쳐다 봤는데 난 그냥 그것을 확인할 수 없습니다. 내가 뭘 놓치고 있니?

+0

ActiveRecord의 어떤 버전을 사용하고 있습니까? 이전 스타일의 해시 조건을 가진 새로운 스타일'scope' 메서드를 사용 했으므로 – maniacalrobot

+0

active_record v4를 사용합니다. 어떻게 다시 써 주겠어? –

+0

지금 진행 상황을 반영하기 위해 질문을 편집했습니다. 나는 내가'얻을 예상치 못한 구문 오류, ((이미 내가 그것을했다 방법을 일하고처럼, 지금은'unread' 범위에 구문을 시도하는) 것을 시도 할 때 –

답변

0

좋아이 그것을 고정에 연결됩니다, 그러나 그것은 나에게 슈퍼 우아한 보이지 않습니다.

scope :unread_by, ->(u){ 
    Notification.joins("LEFT JOIN notifications_users ON notifications.id = notifications_users.notification_id"). 
       where("notifications_users.user_id <> ? OR notifications_users.user_id IS NULL", u.id).uniq 
} 

그래도 작동합니다. 예 - 도움 주셔서 감사합니다. 올바른 방향으로 안내해 주셨습니다.

0

는 액티브 4의 경우

http://guides.rubyonrails.org/active_record_querying.html

완전히 검증되지 않은 범위 블록 내부의 새로운 스타일의 쿼리 인터페이스를 사용해야하지만, 다음과 같은 쿼리를 구성하는 방법에 대한 안내 a를해야한다 : (주 각 방법은 위의 하나)

scope :unread, { 
    joins("LEFT JOIN notifications_users ON notifications.id = notifications_users.notification_id"). 
    where("notifications_users.user_id IS NULL"). 
    select("DISTINCT notifications.*") 
} 

scope :unread_by, ->(u){ 
    joins("LEFT JOIN notifications_users ON notifications.id = notifications_users.notification_id"). 
    where(["notifications_users.user_id IS ?", u.id]). 
    select("DISTINCT notifications.*") 
} 
+0

감사하지만' –

+0

내가 thusly 히 내 첫 번째 범위를 다시 작성했습니다. 'scope : unread, -> {("LEFT JOIN notifications_users ON notifications.id = notifications_users.notification_id") where ("notifications_users.user_id IS NULL"). uniq}'그리고 잘 작동합니다. 두 번째 –

+0

나는'범위를 시도하고있다 :.. unread_by는, - (U) {Notification.joins 어디에 (("LEFT notifications.id = notifications_users.notification_id ON notifications_users 가입")>, "notifications_users.user_id을 <>?" u.id) .uniq}'하지만 내 결과를 내게주는 것은 아닙니다. 내 쿼리 논리가 약간 혼란 스럽습니다. –