I need to create a single query that includes data from the following tables:
*Conversation: a model that groups messages between users
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: a model that keeps track of the users of the conversation
class ConversationParticipant < ActiveRecord::Base
## Associations
belongs_to :conversation
belongs_to :user
## Attributes conversation_id, user_id, seen, created_at, updated_at
end
* Message: a model that keeps track content and sender
class Message < ActiveRecord::Base
belongs_to :conversation
belongs_to :sender, :class_name => "User"
## Attributes sender_id, content, conversation_id, created_at, updated_at
end
*User: a model with attribute name
- limit of (5) recent messages from Message of uniq Conversation
- where
user_id= current_user.id from ConversationParticipant- order
seen=false, thenupdated_at DESCfrom ConversationParticipant- includes Conversation
- includes (Message sender) => User
- includes the other participant from ConversationParticipant => User
Note: includes and select are important, as this question is meant to reduce the number of queries.
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}])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With