0

私のアプリでは、私のモデルはとSinatraの間の HABTM 関係を定義します。私はいくつかのスコープを定義しようとしています。1 つはno に関連付けられたすべてのもので、もう 1 つは特定の.UsersNotificationsNotificationsUsersunreadNotificationsUser

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

クエリ ロジックに欠陥があると思われますが、これを長時間見つめていて、表示されていません。私は何が欠けていますか?

4

2 に答える 2

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
}

しかし、それは機能します。イェーイ - ご協力ありがとうございます。正しい方向に向けてくれました。

于 2013-09-05T23:21:11.223 に答える
0

ActiveRecord 4 では、スコープ ブロック内で新しいスタイルのクエリ インターフェイスを使用する必要があります。

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

完全にテストされていませんが、以下はクエリを構築する方法のガイドです: (各メソッドはその上のメソッドに連鎖していることに注意してください)

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.*")
}
于 2013-09-05T07:38:40.997 に答える