理由からのみの返信をされる必要があります。言い換えれば、どのコメントがデータベースからフェッチされるかを判断する役割しか果たしません。例えば
は、ここでのスコープで実行されるSQLは次のとおりです。
>> comments = Comment.joins(:replies).where(replies: { user_id: [2, 3] })
Comment Load (0.3ms) SELECT "comments".* FROM "comments" INNER JOIN "replies" ON "replies"."comment_id" = "comments"."id" WHERE "replies"."user_id" IN (2, 3)
これは単なる「回答の表と内部結合の結果に基づいてコメントを選択します。」と言っていますすぐに返信がアクセスして、コメントのいずれかの属性ので、回答の結果は、今ほとんど無意味である:それは考慮していないので、
>> comments.first.replies
Reply Load (0.2ms) SELECT "replies".* FROM "replies" WHERE "replies"."comment_id" = ? [["comment_id", 1]]
ActiveRecordのは、回答テーブル内の別の検索を行いますコメント参照のスコープ
Aソリューション
私にはあなたはコメントより返信が心配しているように見えます。そこで私はこのクエリに近づくだろう一つの方法ではなく、回答のテーブルを照会することによってですが、積極的なロードで:
>> replies = Reply.includes(:comment).where(user_id: [2, 3])
Reply Load (0.4ms) SELECT "replies".* FROM "replies" WHERE "replies"."user_id" IN (2, 3)
Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."id" = 1
最後に、あなただけの特定のユーザーIDの応答を持っています。あなたは熱心な読み込みのために既にこのようにコメントを持っています。たとえば、次のようにコメントを書き込むと、余分なフェッチは発生しません。
>> replies.map(&:comment)
しかし、返信が再びコメントモデルの一つの属性、または他のActiveRecordのは、別のフェッチんだろうにアクセスしないように注意してください:
>> replies.map(&:comment).first.replies
Reply Load (0.2ms) SELECT "replies".* FROM "replies" WHERE "replies"."comment_id" = ? [["comment_id", 1]]
それでもこの範囲にしたい場合、それは今返信モデルに行くだろう:
scope :from_users, -> (*user_ids) do
includes(:comment).where(user_id: user_ids)
end
次に呼び出し:
>> Reply.from_users [2, 3]
Reply Load (0.1ms) SELECT "replies".* FROM "replies" WHERE "replies"."user_id" IN (2, 3)
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."id" = 1
私はスプラット演算子*アスタリスク*が多次元配列を作成していると思います。あなたの 'with_replies_by_users'スコープから削除してみてください。 –
@GregAnswer - 私は両方の方法で試してみましたが、私は同じ結果を得ています。 – atarihomestar