このセクションの下に、私の最初の回答があります。私は質問を読み違えて、OP は指定されたユーザーからメッセージを受信したユーザーのリストのみを必要としていると考えました。指定されたユーザーにメッセージを送信したユーザーに関する部分にも気付きませんでした。これが私の更新です。役立つ場合に備えて、元の回答を以下に残します。
このバージョンの回答では、結合と where 句を変更して、クエリが列sender_id
またはrecipient_id
列のいずれかを調べるようにします。
User.joins("INNER JOIN messages ON (messages.sender_id = users.id OR messages.recipient_id = users.id)")
.where("messages.sender_id = ? OR messages.recipient_id = ?", current_user.id, current_user.id).uniq
誤解をお詫び申し上げます。
元の答え:
コンタクトしたすべてのユーザーを取得するには、通常のアクティブ レコード クエリ メソッドを使用するのが最も簡単な方法だと思います。まず、次のようにモデルに を設定しhas_many
ます。User
あなたのUser
モデルで
has_many :messages_sent, class_name: "Message", foreign_key: :sender_id
has_many :messages_received, class_name: "Message", foreign_key: :recipient_id
そして、次のようにリレーションシップを使用して簡単にクエリを実行できます。
User.joins(:messages_received).where(:messages=>{sender_id: current_user.id}).uniq
注:current_user
ターゲット ユーザーの保存に使用するものに置き換えます。
編集
:messages_sent
なぜこれが直接的な関係を使用するよりも優れているのか、誰かが尋ねました。このアプローチの利点は、すべてがデータベース レベルで行われることであり、適切なインデックス作成がその役割を果たします。非常に大きなテーブルがあり、このユーザーが多数のメッセージを送信した場合、アクティブなレコードhas_many
関係を使用するには、大きなコレクションを反復処理して、一意のユーザーを見つけようとする必要があります。
もう少し明確にするために、このクエリは次のような SQL クエリをレンダリングする必要があります。
SELECT users.*
FROM users INNER JOIN messages ON messages.recipient_id = users.id
WHERE messages.sender_id = 1
平易な英語で言えば、これは基本的にデータベースに対して「ユーザー #1 から送信されたメッセージを受信したすべてのユーザーを教えてください」と言うことです。