mongoid范围发现错误的对话

时间:2015-06-27 09:57:20

标签: ruby-on-rails ruby-on-rails-4 mongoid mongoid4

我的模型上有以下范围:

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开始对话,模型返回false,因为对话不存在,我的控制器需要创建一个新的,但是,控制器打开用户A和用户B之间的对话,而不是那个,但它必须在用户A和用户C之间创建一个新的对话,并打开这个对话。

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

更新:

创建第一个会话后,它始终显示第一个会话。我的意思是:

第一次谈话

  • 用户A - 用户B

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

  • 用户A - 用户C,显示对话用户A,B
  • 用户C - 用户B,显示对话用户A,B
  • 用户C - 用户D,显示对话用户A,B

1 个答案:

答案 0 :(得分:2)

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并不意味着“查询已经这个额外条件”,它只是意味着“和任何这些条件”。

你想要的选择器是:

{
  "$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 }
])

据推测,您exists?中的scope跟踪scope跟踪实际上并不存在。如果是,那么你就是在滥用def self.between(sender_id, recipient_id)创建一个简单的旧类方法,并说use strict; use warnings; my ( $col, @fhs ); # Get header's columns my @header = split ' ', <>; # open cols-1 files for appending (array of file handles); write their headers for $col ( 1 .. $#header ) { open $fhs[$col], '>>', "file$col.txt" or die "Unable to open file$col.txt: $!"; print { $fhs[$col] } "$header[0]\t$header[$col]\n"; } # split each record into fields; append fields as new records to their files while (<>) { my @record = split; for $col ( 1 .. $#header ) { print { $fhs[$col] } "$record[0]\t$record[$col]\n"; } } 会更好。