通过HABTM关联属性查询模型
Querying model by attribute of HABTM association
我在两个模型(User 和 Conversation)之间建立了 HABTM 关联。
我希望能够查询登录用户的对话 (current_user.conversations
),将另一个用户的 ID 传递给它,并让它 return 一个由两个用户共享的对话(如果存在的话)。
(一个额外的好处是让查询创建一个,如果不存在的话。)
关联工作正常,所以我可以通过 @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()
,但我无法让它工作。
有什么建议吗?谢谢。
假设您有两个用户 @sender
和 @receiver
,并且他们之间有一个(或更多)对话。查询他们的共享对话的一种可能方法是使用 ActiveRecord 中的 merge
函数。 merge
将select他们之间的对话交集:
@shared_conversations = @sender.conversations.merge(@receiver.conversations)
请注意,结果将是一个集合,而不是个人对话。在 SQL 中,这将转换为 INNER JOIN
。
如果您想修改此查询以创建不存在的对话,则可以使用 first_or_create
。顾名思义,first_or_create
returns 集合中的第一项。如果集合为空,它将创建一个新对象。你可以传递一个块来进一步控制新创建的对象:
@shared_conversations = @sender.conversations.merge(@receiver.conversations).first_or_create do |conversation|
conversation.title = "#{@sender.first_name}'s conversation"
end
您可以在 Rails 文档中找到有关 merge
的更多详细信息:http://apidock.com/rails/ActiveRecord/SpawnMethods/merge。
试试看
current_user.conversations.includes(:users).where(user.id:current_user.id)
我在两个模型(User 和 Conversation)之间建立了 HABTM 关联。
我希望能够查询登录用户的对话 (current_user.conversations
),将另一个用户的 ID 传递给它,并让它 return 一个由两个用户共享的对话(如果存在的话)。
(一个额外的好处是让查询创建一个,如果不存在的话。)
关联工作正常,所以我可以通过 @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()
,但我无法让它工作。
有什么建议吗?谢谢。
假设您有两个用户 @sender
和 @receiver
,并且他们之间有一个(或更多)对话。查询他们的共享对话的一种可能方法是使用 ActiveRecord 中的 merge
函数。 merge
将select他们之间的对话交集:
@shared_conversations = @sender.conversations.merge(@receiver.conversations)
请注意,结果将是一个集合,而不是个人对话。在 SQL 中,这将转换为 INNER JOIN
。
如果您想修改此查询以创建不存在的对话,则可以使用 first_or_create
。顾名思义,first_or_create
returns 集合中的第一项。如果集合为空,它将创建一个新对象。你可以传递一个块来进一步控制新创建的对象:
@shared_conversations = @sender.conversations.merge(@receiver.conversations).first_or_create do |conversation|
conversation.title = "#{@sender.first_name}'s conversation"
end
您可以在 Rails 文档中找到有关 merge
的更多详细信息:http://apidock.com/rails/ActiveRecord/SpawnMethods/merge。
试试看 current_user.conversations.includes(:users).where(user.id:current_user.id)