0

私はUserモデルと とのモデルをMessage持っています。sender_idrecipient_id

私が連絡した、または連絡を受けたすべてのユーザーを取得したいと思います。

私は試した :

  has_many :message_received_by_user, class_name: 'Message', foreign_key: :recipient_id, select: "DISTINCT ON (messages.sender_id) messages.sender_id, messages.created_at, messages.body" , order: "messages.sender_id, messages.created_at DESC"

しかし、これは私に片面しか与えません(私に連絡した人)。

どうすれば両面を持つことができますか?

どうもありがとう

4

3 に答える 3

2

このセクションの下に、私の最初の回答があります。私は質問を読み違えて、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 から送信されたメッセージを受信したすべてのユーザーを教えてください」と言うことです。

于 2013-11-13T14:01:45.297 に答える
0

railscast http://railscasts.com/episodes/163-self-referential-associationを参照するか、ソーシャル ネットワーキング アプリケーション用に Rails 3 でフレンドシップ モデルを実装する方法は?

私はそれをmongoidで実装します

ユーザーモデル

has_many :friendships, inverse_of: :owner

def friends
  #retrive all the friendships and collect users have sent me a request or being sent a  request.
  fs = Friendship.any_of({:friend_id.in => [self.id]}, {:owner_id.in => [self.id]}).where(state: 'accepted')
  User.in(id: fs.collect{|i| [i.friend_id, i.owner_id]}.flatten - [self.id])
end

友情モデル

 belongs_to :owner, class_name: 'User' #user who sent friend request is the owner
 belongs_to :friend, class_name: "User" #user to whom request is sent.
于 2013-11-13T14:03:40.027 に答える
0

次のようにできます。

移行は次のようになります。

class CreateMessages < ActiveRecord::Migration
  create_table :messages do |t|
    def up
      t.references :sender
      t.references :recipient
      t.string :message
    end
  end
end

モデル:-

class Message < ActiveRecord::Base
  belongs_to :sender, class_name => 'User'
  belongs_to :recipient, class_name => 'User'
end

そして、これらの他のものは、反対側 (ユーザー モデル) の関連付けです。

class User < ActiveRecord::Base
 has_many :sent_messages, :class_name => 'Message', :foreign_key => 'sender_id'
 has_many :received_messages, :class_name => 'Message', :foreign_key => 'recipient_id'
end

これにより、次のようなユーザーの送受信メッセージをすべて取得できます。

@user.sent_messages
@user.received_messages

ありがとう

于 2013-11-13T13:58:57.160 に答える