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 之间创建一个新对话,并打开这个对话。

我做错了什么??我尝试了不同的浏览器并清理了我的缓存。


更新:

创建第一个对话后,它总是显示第一个对话。我的意思是:

第一次对话

正在尝试在以下用户之间创建其他对话:

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) 会是一个更好的主意。