Rails の ActiveRecord で次のクエリを実行するのに苦労しています。
私のスキーマは多かれ少なかれ次のようになっています。
1対多の関係 (つまりと)quests
で関連付けられている table があります。solutions
quest has_many solutions
solution belongs_to quest
solutions
guilds
は、1 対多 (つまりguild has_many solutions
と) によっても関連付けられsolution belongs_to guild
ます。
solutions
score
整数列があります。
私が望むのは、特定のクエストに対して各ギルドの最高スコアでソリューションを取得することです。SQLでは、私はこのようなものを書くと思います。
SELECT quests.id, solutions.*, max(solutions.score)
FROM quests
INNER JOIN solutions ON solutions.quest_id = quests.id
WHERE quests.id IN (1, 2, 3 or whatever I want to fetch)
GROUP BY solutions.guild_id, quests.id;
これらの多くを単一のページに表示するため、これQuest
をクラスの関係として機能させて、次のような方法でこれらをプリフェッチできるようにしようとしています。Quest.includes(:best_solutions).limit(40)
これが私が試したものです(Quest
モデル内)。
has_many :best_solutions,
-> { select('solutions.*, max(solutions.score)')
.group('solutions.guild_id', 'solutions.quest_id')
.readonly },
class_name: 'Solution',
foreign_key: 'quest_id'
を試してみたところ、非常に満足しQuest.first.best_solutions
ました。結果は次のとおりです。
SELECT solutions.*, max(solutions.score)
FROM "solutions"
INNER JOIN "quests"
ON "quests"."id" = "solutions"."quest_id"
WHERE "solutions"."quest_id" = ?
GROUP BY solutions.guild_id, quests.id
ただし、それを と組み合わせようとするとincludes
、得られるクエリは取得しようとしているものとは何の関係もありません。たとえばQuest.includes(:best_solutions).load
、
SELECT solutions.*, max(solutions.score)
FROM "solutions"
WHERE "solutions"."quest_id" IN (1, 2......)
ここで何が欠けているのか誰かが説明してくれませんか。
ありがとうございました。