Mysql Rails基于缺少与条件关联的模型来查询一个模型

Mysql Rails基于缺少与条件关联的模型来查询一个模型,mysql,sql,ruby-on-rails,database,ruby-on-rails-3,Mysql,Sql,Ruby On Rails,Database,Ruby On Rails 3,我总是在基于多个关联模型进行查询和基于缺少关联模型进行查询时遇到问题 因此,我尝试为每个特定用户实现一种将消息标记为已读或未读的方法。以下是我正在使用的模型: class Stock < ActiveRecord::Base has_many :messages end class Message < ActiveRecord::Base belongs_to :stock has_many :message_viewings end class MessageVie

我总是在基于多个关联模型进行查询和基于缺少关联模型进行查询时遇到问题

因此,我尝试为每个特定用户实现一种将消息标记为已读或未读的方法。以下是我正在使用的模型:

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
尝试以下方法:

Stock.joins(messages: :message_viewings).where("message_viewings.user_id != ? or message_viewings.user_id is null", current_user.id)
只需确保当前用户已设置

更新代码 如果您想要所有没有属于当前用户的消息的股票,请执行以下操作:

@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)
我认为您编写的代码中有一个错误,因为如果消息查看中存在用户id,那么消息查看的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)

如果愿意,您可以将最终查询转换为一种方法。

这几乎就是我想要的,但我确实需要包含没有任何用户查看的消息。请尝试更新的代码,尽管对我来说,使用includes而不是join时效果更好。我感谢您的努力,我设法找到了一个与我的目标类似的相关宝石:。它被很好地记录下来,足以让我整理出一个似乎有效的查询。由于我是新用户,我无法回答自己的问题,因此我已编辑了您的问题。请使用代码更新您的问题,让我们看看是否可以简化。我已更新了我的答案,希望它能帮助您。
# 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)