默认情况下:completed_at为nil。如果我使用完整方法,那么completed_at将变为Time.now。我检查了它,它工作正常。 尽管如此,我的查询在传入/传出任务的情况下不起作用。查询与已完成的任务完美匹配真是奇怪。所以"其中"查询不起作用,但" where.not"确实。你能帮我解决这个问题吗?
def incoming_tasks
@user =current_user
@executed_tasks = @user.executed_tasks.where("completed_at = ?", 'nil').order("created_at DESC")
end
def outgoing_tasks
@user = current_user
@assigned_tasks = @user.assigned_tasks.where("completed_at = ?", 'nil').order("created_at DESC")
end
def completed_tasks
@user = current_user
@assigned_tasks = @user.assigned_tasks.where.not("completed_at = ?", 'nil').order("completed_at DESC")
@executed_tasks = @user.executed_tasks.where.not("completed_at = ?", 'nil').order("completed_at DESC")
end
以下是我使completed_at属性具有日期的方式:
def complete
@task = Task.find(params[:id])
@task.update_attribute(:completed_at, Time.now)
redirect_to completed_tasks_user_tasks_path(current_user)
end
答案 0 :(得分:2)
如上所述,您需要使用IS
关键字生成SQL,以确定列是否为NULL
。您可以将哈希值传递给where
,让ActiveRecord处理微妙之处,而不是自己争吵;即:
def incoming_tasks
@user =current_user
@executed_tasks = @user.executed_tasks.where(completed_at: nil).order("created_at DESC")
end
def outgoing_tasks
@user = current_user
@assigned_tasks = @user.assigned_tasks.where(completed_at: nil).order("created_at DESC")
end
def completed_tasks
@user = current_user
@assigned_tasks = @user.assigned_tasks.where.not(completed_at: nil).order("completed_at DESC")
@executed_tasks = @user.executed_tasks.where.not(completed_at: nil).order("completed_at DESC")
end
顺便说一句,这将是一个使用范围的好地方。
修改详细信息:
(警告:SQL是一个规范,而不是一个实现,rails生成的SQL依赖于数据库适配器。以下内容可能因您选择的数据库而异。)
好的,有些事情:
您正在使用where("completed_at = ?", 'nil')
,它实际上正在查找completed_at
是字符串 "nil"
的记录。这几乎肯定不是你想要的,并且还有其他意想不到的后果。
在匹配行时,SQL有一种非常特殊的方法来处理NULL
值。在=
子句中使用WHERE
运算符时,它将忽略具有NULL
值的行。您必须使用其中一个IS NULL
或IS NOT NULL
运算符来推理NULL
值。
考虑一下表:
| id | completed_at |
| 1 | 2015-07-11 23:23:19.259576 |
| 2 | NULL |
使用以下查询:
Rails | SQL | Result
where("completed_at = ?", 'nil') | WHERE (completed_at = 'nil') | nothing, since completed_at isn't even a string
where.not("completed_at = ?", 'nil') | WHERE (NOT (completed_at = 'nil')) | only row 1, since = can't match a NULL value, even when negated
where("completed_at = ?", nil) | WHERE (completed_at = NULL) | nothing, you can't test for NULL with the = operator
where.not("completed_at = ?", nil) | WHERE (NOT (completed_at = NULL)) | nothing, you can't test for not NULL with = either
where(completed_at: nil) | WHERE completed_at IS NULL | row 2 only
where.not(completed_at: nil) | WHERE (completed_at IS NOT NULL) | row 1 only
当然,where(completed_at: nil)
只是where('completed_at IS NULL')
的简写,反之亦然,但哈希格式更加惯用且独立于数据库适配器。
所有这一切的神奇之处在于ActiveRecord能够通过查看传递给=
的哈希来确定它是否应该使用IS NULL
或where
。如果你传递一个片段,它就不知道了,所以它盲目地应用它。