1

我在两个模型之间有一个 HABTM 关联,​​用户和对话。我希望能够查询登录用户的对话(current_user.conversations),将另一个用户的 id 传递给它,并让它返回一个由两个用户共享的对话(如果存在的话)。(如果一个查询不存在,另一个好处是让查询创建一个。)

关联工作正常,所以我可以通过实例变量访问关联的对象@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()到某种方式,但我无法让它工作。

有什么建议吗?谢谢。

4

2 回答 2

1

假设您有两个用户@sender@receiver,并且他们之间有一个(或者可能更多)对话。查询他们共享对话的一种可能方法是使用mergeActiveRecord 中的函数。merge将选择它们之间的对话交集:

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

请注意,结果将是一个集合,而不是一个单独的对话。在 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

merge您可以在 Rails 文档中找到更多详细信息:http: //apidock.com/rails/ActiveRecord/SpawnMethods/merge

于 2016-04-19T03:31:30.587 回答
0

试试 current_user.conversations.includes(:users).where(user.id:current_user.id)

于 2016-04-19T03:34:38.297 回答