我的模型上有以下范围:
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之间创建一个新的对话,并打开这个对话。
我做错了什么?我试过不同的浏览器并清理缓存。
更新:
创建第一个会话后,它始终显示第一个会话。我的意思是:
第一次谈话
尝试在以下用户之间创建其他对话:
答案 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";
}
}
会更好。