Reputation: 161
I am stuck in a rails problem, being a noob here. Given the following relationships.
conversation has_many messages
messages belongs_to conversation
messages has_many documents and vice versa, through document_messages
I need to find all documents in that conversation for a given conversation id. I got it working with following
c.messages.map(&:documents).select{ |doc| doc.length > 0 }
But as I understand it takes everything from database and does filtering on the application, but I need to filter it on the database (where clause?) for e.g. conversation.messages.where(document.exists).map(&:documents)
Edit: I came up with following sql query which is working
SELECT document.id FROM
conversation INNER JOIN message
ON conversation.id = message.c_id
INNER JOIN document_messages
ON message.id = document_messages.m_id
INNER JOIN document
ON document.id = document_messages.d_id
where conversation.id = given_id
Upvotes: 1
Views: 183
Reputation: 161
So, I finally managed to write the query.
Document.joins(document_messages: [{ message: :conversation }]).where(conversations: { id: conversation_id})
which can be simplified to
Document.joins(messages: :conversation).where(conversations: { id: conversation_id})
Upvotes: 1
Reputation: 48
Not entirely confident with how this plays with a join table but this could be what you need?
Something like:
messages = conversation.messages.includes(:documents)
documents = messages.documents
Upvotes: 0
Reputation: 1287
Use Through association: https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
Conversation
has_many :messages
has_many :documents, through: :messages
end
Messages
belongs_to :conversation
has_many :documents
end
Using this, you can do the following:
conversation = Conversation.first
conversation.documents
And you have all documents of a conversation!
Upvotes: 1