0

私は常に、複数の関連付けられたモデルに基づいてクエリを実行したり、関連付けられたモデルがないことに基づいてクエリを実行したりするときに問題を抱えていました。

そのため、特定のユーザーごとにメッセージを既読または未読としてマークする方法を実装しようとしています。これらは私が取り組んでいるモデルです:

class Stock < ActiveRecord::Base
  has_many :messages
end

class Message < ActiveRecord::Base
  belongs_to :stock
  has_many :message_viewings
end

class MessageViewing < ActiveRecord::Base
  belongs_to :user
  belongs_to :message
end

class User < ActiveRecord::Base
  has_many :message_viewings
end

私の目標は、特定のユーザーによる MessageViewings を欠いているメッセージを持つすべての株式を見つけることです。未読メッセージがあるかどうかをユーザーに示すことができるように、この情報が必要です。これまでのところ、言及する価値のある試みはありません。

アップデート

さらに検索すると、うまく文書化された宝石にたどり着きまし。そこにリストされているクエリを少し変更して、この新しいクエリにたどり着きました。これは、私がやりたいことを実現しているように見えますが、それがどれほど効率的であるかはわかりません。

Stock.joins(:messages).joins("LEFT JOIN message_viewings ON \
  message_viewings.message_id = messages.id AND \
  message_viewings.user_id = #{User.sanitize(current_user.id)}").where(
  "message_viewings.id IS NULL")
4

1 に答える 1

0

次のようなものを試してください:

Stock.joins(messages: :message_viewings).where("message_viewings.user_id != ? or message_viewings.user_id is null", current_user.id)

現在のユーザーが設定されていることを確認してください。

更新されたコード

現在のユーザーに属する message_viewing を持たないすべての株式が必要な場合は、次のようにします。

@user = # code to retrieve user
Stock.joins(:messages).joins("LEFT JOIN message_viewings ON message_viewings.message_id = messages.id").where("message_viewings.user_id != ? OR message_viewings.id IS NULL", @user.id)

message_viewing の user_id が存在する場合、message_viewing の id は null にならないため、記述したコードに誤りがあると思います。

私はおそらくそのコードをストックモデルに入れます:

# stock model
def self.join_message_viewings
  joins(:messages).joins("LEFT JOIN ... ")
end

def self.unread_by(user_id)
  .where("messages_viewings.user_id != ... ", user_id)
end

# query
Stock.join_message_viewings.unread_by(@user.id)

必要に応じて、最終的なクエリを 1 つのメソッドにすることもできます。

于 2013-02-26T22:15:49.213 に答える