0

我有一个User模型和Message一个带有sender_idand的模型recipient_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_idorrecipient_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

你可以这样做:

您的迁移将如下所示:

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 回答
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 回答