我如何加入 has_many、has_many :through 和 HABTM?

How can I join across a has_many, a has_many :through and a HABTM?

我希望能够编写一个查询来查找用户创建、查看或接收的所有消息。

这是我的用户的简化版本class:

class User < ActiveRecord::Base
  # user_id
  has_many :messages

  # message_viewer_id
  has_many :message_views, foreign_key: 'message_viewer_id'
  has_many :viewed_messages, through: :message_views

  # user_id
  has_and_belongs_to_many :received_messages,
                          join_table: 'messages_recipients',
                          class_name: 'Message'
end

我尝试了以下使用 .where.conditions 的多种变体,但不断出现 PG::UndefinedTable: ERROR: missing FROM-clause entry for table "received_messages"

之类的错误
User.
  joins(:messages,
        :message_views,
        :received_messages).
  where({messages: {user_id: id},
         message_views: {message_viewer_id: id},
         received_messages: {user_id: id}})

(我可以毫无问题地加入 :messages:message_views,但是当我引入 :received_messages 时查询中断。(是的,我知道我不应该使用 HABTM。) )

最简单and/or最有效的方法是什么?

尝试这样的事情:

class User < ActiveRecord::Base
   ...
    def all_messages
      Message.where("user_id = ? OR id IN (SELECT message_id FROM message_views WHERE message_viewer_id = ?) OR id IN (SELECT message_id FROM messages_recipients WHERE user_id = ?)", self.id, self.id, self.id)
    end
    ...
end

我建议在消息 user_id 上放置索引,在 message_views 上放置索引 message_viewer_id,在 messages_recipients 上放置索引 user_id,如果您还没有的话.