mongoid 作用域发现错误的对话
mongoid scope find the wrong conversation
我的模型有以下范围:
scope :between, -> (sender_id,recipient_id) do
where(sender_id: sender_id, recipient_id: recipient_id).or(sender_id: recipient_id, recipient_id: sender_id).exists?
end
这个尝试找到两个人之间的对话,在我的控制器上我有以下操作:
def create
if Conversation.between(params[:sender_id],params[:recipient_id]).exists?
@conversation = Conversation.between(params[:sender_id],params[:recipient_id]).first
redirect_to dashboard_conversation_path(@conversation.id)
else
@conversation = Conversation.create!(conversation_params)
redirect_to dashboard_conversation_path(@conversation.id)
end
end
这是我的问题:
我还有 3 个用户:
用户,A、B、C、D...任何人之间都没有对话。我创建用户A和用户B的对话,对话不存在,所以创建,那么如果用户A想和用户C开始对话,模型return false,因为对话不存在,儿子我的控制器需要创建一个新的,但是,控制器不是那样,而是打开用户 A 和用户 B 之间的对话,但它必须在用户 A 和用户 C 之间创建一个新对话,并打开这个对话。
我做错了什么??我尝试了不同的浏览器并清理了我的缓存。
更新:
创建第一个对话后,它总是显示第一个对话。我的意思是:
第一次对话
- 用户 A - 用户 B
正在尝试在以下用户之间创建其他对话:
- 用户A - 用户C,显示对话用户A,B
- 用户 C - 用户 B,显示对话用户 A,B
- 用户 C - 用户 D,显示对话用户 A,B
or
方法并不像您想象的那样起作用。如果您查看底层选择器:
Conversation.where(sender_id: s, recipient_id: r).or(sender_id: r, recipient_id: s).selector
你会看到这个:
{
"sender_id" => s,
"recipient_id" => r,
"$or" => [
{
"sender_id" => r,
"recipient_id" => s,
}
]
}
在查询中调用 or
并不意味着 "whatever is in the query already or this extra condition",它只是意味着 "and any of these conditions"。
您想要的选择器是:
{
"$or" => [
{ "sender_id" => s, "recipient_id" => r },
{ "sender_id" => r, "recipient_id" => s }
]
}
这将通过单个 or
调用构建:
or([
{ sender_id: s, recipient_id: r },
{ sender_id: r, recipient_id: s }
])
据推测,您的 scope
中尾随的 exists?
调用实际上并不存在。如果是,那么你就是在滥用 scope
来创建一个普通的旧 class 方法,然后说 def self.between(sender_id, recipient_id)
会是一个更好的主意。
我的模型有以下范围:
scope :between, -> (sender_id,recipient_id) do
where(sender_id: sender_id, recipient_id: recipient_id).or(sender_id: recipient_id, recipient_id: sender_id).exists?
end
这个尝试找到两个人之间的对话,在我的控制器上我有以下操作:
def create
if Conversation.between(params[:sender_id],params[:recipient_id]).exists?
@conversation = Conversation.between(params[:sender_id],params[:recipient_id]).first
redirect_to dashboard_conversation_path(@conversation.id)
else
@conversation = Conversation.create!(conversation_params)
redirect_to dashboard_conversation_path(@conversation.id)
end
end
这是我的问题:
我还有 3 个用户:
用户,A、B、C、D...任何人之间都没有对话。我创建用户A和用户B的对话,对话不存在,所以创建,那么如果用户A想和用户C开始对话,模型return false,因为对话不存在,儿子我的控制器需要创建一个新的,但是,控制器不是那样,而是打开用户 A 和用户 B 之间的对话,但它必须在用户 A 和用户 C 之间创建一个新对话,并打开这个对话。
我做错了什么??我尝试了不同的浏览器并清理了我的缓存。
更新:
创建第一个对话后,它总是显示第一个对话。我的意思是:
第一次对话
- 用户 A - 用户 B
正在尝试在以下用户之间创建其他对话:
- 用户A - 用户C,显示对话用户A,B
- 用户 C - 用户 B,显示对话用户 A,B
- 用户 C - 用户 D,显示对话用户 A,B
or
方法并不像您想象的那样起作用。如果您查看底层选择器:
Conversation.where(sender_id: s, recipient_id: r).or(sender_id: r, recipient_id: s).selector
你会看到这个:
{
"sender_id" => s,
"recipient_id" => r,
"$or" => [
{
"sender_id" => r,
"recipient_id" => s,
}
]
}
在查询中调用 or
并不意味着 "whatever is in the query already or this extra condition",它只是意味着 "and any of these conditions"。
您想要的选择器是:
{
"$or" => [
{ "sender_id" => s, "recipient_id" => r },
{ "sender_id" => r, "recipient_id" => s }
]
}
这将通过单个 or
调用构建:
or([
{ sender_id: s, recipient_id: r },
{ sender_id: r, recipient_id: s }
])
据推测,您的 scope
中尾随的 exists?
调用实际上并不存在。如果是,那么你就是在滥用 scope
来创建一个普通的旧 class 方法,然后说 def self.between(sender_id, recipient_id)
会是一个更好的主意。