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 的所有带有 Messages 的 Stocks。我想要这些信息,这样我就可以向用户表明他们是否有未读消息。到目前为止,我的任何尝试都不值得一提。

更新

进一步的搜索使我找到了一个记录良好的 gem,几乎可以满足我的要求:https ://github.com/ledermann/unread 。获取那里列出的查询并对其进行一些修改,我来到了这个新查询,它似乎可以完成我想要完成的工作,尽管我不确定它的效率如何:

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 不会为空。

我可能会将该代码放入库存模型中:

# 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)

如果您愿意,可以将最终查询变成一种方法。

于 2013-02-26T22:15:49.213 回答