包含,选择,排序,限制多个模型(单个查询)

时间:2014-11-11 23:02:17

标签: mysql ruby-on-rails postgresql activerecord ruby-on-rails-4

我需要创建一个包含以下表格数据的查询:

*对话:在用户之间对邮件进行分组的模型

class Conversation < ActiveRecord::Base
  # Associations
  has_many :messages, dependent: :destroy
  has_many :conversation_participants
  has_many :users, :through => :conversation_participants
  ## Attributes title, created_at, updated_at
end

* ConversationParticipant :跟踪对话用户的模型

class ConversationParticipant < ActiveRecord::Base
  ## Associations
  belongs_to :conversation
  belongs_to :user
  ## Attributes conversation_id, user_id, seen, created_at, updated_at
end

*消息:保留跟踪内容和发件人的模型

class Message < ActiveRecord::Base
  belongs_to :conversation
  belongs_to :sender, :class_name => "User"
  ## Attributes sender_id, content, conversation_id, created_at, updated_at
end

*用户:具有属性name

的模型

如何在单个查询中获取以下内容?

  
      
  1. 限制(5)来自uniq 对话的 消息 的近期消息
  2.   来自 ConversationParticipant
  3. 其中 user_id = current_user.id   
  4. 订单 seen = false,然后来自 ConversationParticipant
  5. updated_at DESC   
  6. 包含 对话
  7.   
  8. 包含 消息 发件人)=&gt;的 用户
  9.   
  10. 包括来自 ConversationParticipant =&gt;的其他参与者用户
  11.   

注意: 包含 选择 非常重要,因为此问题旨在减少查询次数

1 个答案:

答案 0 :(得分:2)

以下是我如何包含所有需要的模型,这个查询被转换为5个sql查询,因为preload没有加入(在单独的查询中运行)。

Message.joins("LEFT JOIN messages AS m ON messages.id != m.id 
              AND m.conversation_id = messages.conversation_id 
              AND messages.created_at < m.created_at")
       .where('m.id IS NULL')
       .joins("INNER JOIN conversation_participants AS cp 
              ON cp.conversation_id = messages.conversation_id 
              AND cp.user_id = #{user_id}")
       .order("cp.seen, cp.updated_at DESC")
       .limit(5)
       .includes(:sender)
       .includes(conversation: [{conversation_participants: :user}])