1

私は2つのモデル、ユーザーと会話の間にHABTMの関連付けをしています。 ログインしているユーザーの会話(current_user.conversations)を照会し、別のユーザーのIDを渡して、両方のユーザーが共有している会話を返すようにしたいと考えています。 (追加特典は、1が存在しない場合、クエリは1を作成してもらうことであろう。)HABTMアソシエーションの属性別にモデルを照会

団体が正常に動作しているので、私は@user.conversations@conversation.usersなどのインスタンス変数を介して関連付けられたオブジェクトにアクセスすることができますので、私は行くことができますそれぞれの会話オブジェクトを遠ざけてループし、それぞれのユーザーの関連付けを検索します...しかし、このクエリを構築するには効率的な方法が必要です。 私ができることを望むのは、current_user.conversations.where(conversation.users.exists?(id: @user_id))など、Conversation.find(users: {id: @user_id AND current_user.id})のようなものです。

私はこれに明らかな答えがあると思います。私はここで同様の質問をしていますが、何も見つけられていません。 Rails APIのドキュメントを見てから、私が探している解決策は何とか.includes()になると思っていますが、うまく動作しません。

アドバイスはありますか?ありがとう。

+0

あなたはユーザーとの会話の間の関係をモデル化し、高レベルのスニペットを投稿することができますか?会話にはユーザーごとに外部キーが設定されていますか(例: 'sender_id'、' recipient_id')? –

答えて

1

2人のユーザー@sender@receiverがあり、それらの間に1つ(または多分)の会話があるとします。共有会話を照会する方法として、ActiveRecordのmerge機能を使用する方法があります。結果は、コレクションではなく、個々の会話になることを

@shared_conversations = @sender.conversations.merge(@receiver.conversations) 

注:mergeは、それらの間の会話の交点を選択します。 SQLでは、これはINNER JOINに変換されます。

会話が存在しない場合は、このクエリを修正して会話を作成する場合は、first_or_createを使用できます。その名の通り、first_or_createはコレクションの最初の項目を返します。コレクションが空の場合、新しいオブジェクトが作成されます。あなたはそれを新しく作成されたオブジェクトの上に更なる制御のためのブロックを渡すことができます。

@shared_conversations = @sender.conversations.merge(@receiver.conversations).first_or_create do |conversation| 
    conversation.title = "#{@sender.first_name}'s conversation" 
end 

あなたはRailsのドキュメントでmergeの詳細を見つけることができます:http://apidock.com/rails/ActiveRecord/SpawnMethods/merge

+1

ありがとう、これはまさに私が探していたものです! しかし、私は の '@ sender.conversations.merge(@ receiver.conversations).first_or_create'、 と同等のものを呼び出して会話が存在しなかった場合、会話を作成しました@送信者はそれに関連していました。ループを追加し、 '@ sender.conversations.merge(@ receiver.conversations).first_or_create do | conversation | conversation.users << @receiver end' 希望どおりに動作するようですが、 もう一度おねがいします! –

0

current_user.conversations.includes試してみてください(:ユーザー).where(user.id:current_user.id)

関連する問題