かなり複雑な熱心なロードを作成しようとしています。最初のステートメントではなく、2 番目のステートメントを変更したいと思います。別のテーブルの列を含む 2 番目のステートメントで結合を作成する必要があります。
私が試みるすべてのことは、最初のステートメントを変更し、2 番目のステートメントをそのまま残します。N+1 クエリを使用せずに同じタスクを達成する別の方法がある場合は、オープンです。
これ:
Conversation.joins(:phones)
.where('phones.id' => 2)
.order('last_message_at DESC')
.includes(:messages)
生成:
SELECT "conversations".* FROM "conversations"
INNER JOIN "conversations_phones"
ON "conversations_phones"."conversation_id" = "conversations"."id"
INNER JOIN "phones"
ON "phones"."id" = "conversations_phones"."phone_id"
WHERE "phones"."id" = 2 ORDER BY last_message_at DESC
SELECT "messages".* FROM "messages"
WHERE "messages"."conversation_id" IN (10, 11) ORDER BY created_at ASC
理にかなっていますが、私がなりたい場所ではありません。
必要な 2 番目のステートメントを次のように記述できます。
Message.joins(:message_tags)
.select('messages.*, message_tags.status as read')
.group('messages.id, message_tags.status')
.order('messages.id')
.where(:message_tags => { :user_id => current_user.id })
.where(:messages => { :conversation_id => [10, 11] })
正しく生成するもの:
SELECT messages.*, message_tags.status as read FROM "messages"
INNER JOIN "message_tags" ON "message_tags"."message_id" = "messages"."id"
WHERE "message_tags"."user_id" = 2 AND "messages"."conversation_id" IN (10, 11)
GROUP BY messages.id, message_tags.status
ORDER BY messages.id
基本的に、新しいクエリを作成せずに @conversations.first.messages.first.read を呼び出すことができるように、より複雑なメッセージを選択して単純なものに置き換えたいと考えています。