Ruby on rails 上次联系的用户

Ruby on rails 上次联系的用户,ruby-on-rails,Ruby On Rails,我有一个用户模型和一个带有发送者id和接收者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:

我有一个用户模型和一个带有发送者id和接收者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"
但这只给了我联系我的人一面

我怎么能两面都要

非常感谢

您可以这样做:

class CreateMessages < ActiveRecord::Migration
  create_table :messages do |t|
    def up
      t.references :sender
      t.references :recipient
      t.string :message
    end
  end
end
@user.sent_messages
@user.received_messages
SELECT users.* 
FROM users INNER JOIN messages ON messages.recipient_id = users.id 
WHERE messages.sender_id = 1
您的迁移将如下所示:

class CreateMessages < ActiveRecord::Migration
  create_table :messages do |t|
    def up
      t.references :sender
      t.references :recipient
      t.string :message
    end
  end
end
@user.sent_messages
@user.received_messages
SELECT users.* 
FROM users INNER JOIN messages ON messages.recipient_id = users.id 
WHERE messages.sender_id = 1

谢谢

下面这部分是我的原始答案;我看错了问题,认为OP只想要一个从指定用户那里收到消息的用户列表;我没有注意到关于向指定用户发送消息的用户的部分。这是我的更新。如果有帮助的话,我会把原始答案留在下面

在这个版本的答案中,我将修改join和where子句,以便查询检查sender\u id或recipient\u id列:

为误会道歉

原始答复:

为了获得您联系过的所有用户,我认为最简单的方法是通过正常的活动记录查询方法来实现。首先,在您的用户模型中设置has_many,如下所示:

在您的用户模型中

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
然后,您可以简单地使用如下关系进行查询:

User.joins(:messages_received).where(:messages=>{sender_id: current_user.id}).uniq
注意:将当前_用户替换为用于存储目标用户的任何内容

编辑

有人问,为什么这比使用“直接:消息发送”关系要好。这种方法的优点是,它都是在数据库级别完成的,适当的索引可以完成它的工作。如果您有一个非常大的表,并且该用户已发送了大量消息,那么使用active record has_许多关系将需要您迭代一个大型集合,试图找到唯一的用户

为了进一步说明,此查询应呈现如下所示的SQL查询:

class CreateMessages < ActiveRecord::Migration
  create_table :messages do |t|
    def up
      t.references :sender
      t.references :recipient
      t.string :message
    end
  end
end
@user.sent_messages
@user.received_messages
SELECT users.* 
FROM users INNER JOIN messages ON messages.recipient_id = users.id 
WHERE messages.sender_id = 1
简单地说,这基本上是对数据库说:请给我所有收到用户1发送的消息的用户。

参考railscast或

我在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.

has many关系必须是由用户接收的复数消息,并且属于单数。这是否意味着我无法使用has many实现我想做的事情?我想要不同的用户,而不是消息!是的,是我!我删除了评论,因为我没有正确阅读问题!您的答案仍然缺少一种方法来获取向目标用户发送或接收消息的用户,但我不确定在一个查询中不写消息就可以做到这一点SQL@Slicedpan没问题,这是个公平的问题。嗯,我不太清楚你的意思。回复:你评论的第二部分。正在用户模型上调用活动记录查询方法。最终,这将生成一个如下查询:SELECT users.*FROM users INNER JOIN messages ON messages.RECTIVER\u id=users.id WHERE messages.sender\u id=1。你可以看到,除非我真的错过了什么,您确实会返回从目标用户接收消息的用户列表。我认为您需要的查询是选择用户。*从用户内部将消息作为r_msg ON r_msg.recipient_id=users.id内部将消息作为s_msg ON s_msg.sender_id=users.id,其中s_msg.recipient_id=1或r_msg.recipient_id=1;i、 e.从用户1收到消息或向用户发送消息的所有用户1@Slicedpan哦,胡说,我明白你的意思了。我看错了问题,认为OP只需要接收消息的用户,而不是向该用户发送消息的用户。非常感谢。我会更新。我想用户。加入:messages\u sent,:messages\u received将自动创建别名,但我找不到别名的确切来源。