2016-08-16 6 views
0
class Comment < ActiveRecord::Base 
    has_many :replies 
end 

class Reply < ActiveRecord::Base 
    belongs_to :comment 
end 

特定のユーザーからの返信しかないコメントを取得する必要があります。has_many関係のbelongs_toモデルの一部しか取得できません。

は、私は私のコメントのモデルでこれを持っている:

scope :with_replies_by_users, ->(*user_ids) { 
joins(:replies).where(replies: { user_id: user_ids }) 
} 


@comments = Comment.with_replies_by_users([1,2]) 

私は、これは1または2での返信を持っているすべてのコメントを返すになると思う。しかし、それはそれらのコメントに返事のすべてを返します。これらの条件は、コメントを照会するために使用されているので、私はあなたがまだあなたのスコープの例で、すべてのユーザーからのすべての応答を取得する1または2

+0

私はスプラット演算子*アスタリスク*が多次元配列を作成していると思います。あなたの 'with_replies_by_users'スコープから削除してみてください。 –

+0

@GregAnswer - 私は両方の方法で試してみましたが、私は同じ結果を得ています。 – atarihomestar

答えて

0

理由からのみの返信をされる必要があります。言い換えれば、どのコメントがデータベースからフェッチされるかを判断する役割しか果たしません。例えば

は、ここでのスコープで実行される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 
関連する問題