在使用where.not和Rails时混淆结果

时间:2016-06-08 18:34:46

标签: ruby-on-rails activerecord

我有一个带有付款状态字符串字段的订单模型。通常这个字段应该填充,但有时它是零。我有以下范围

scope :not_pending, -> { where.not(payment_status: 'pending') }

在我的一个测试中,对于订单,payment_status是零,但我仍然得到范围的空结果。如果我更改它以删除.not,我会再次得到一个空结果,所以我有点困惑。

编辑 - 添加了SQL

"SELECT "orders".* FROM "orders" INNER JOIN "order_compilations" ON "orders"."id" = "order_compilations"."order_id" WHERE "order_compilations"."menu_group_id" = 3724 AND ("orders"."payment_status" != 'pending')"

3 个答案:

答案 0 :(得分:1)

只需添加nil,然后检查两者

scope :not_pending, -> { where.not(payment_status: 'pending').or(payment_status: nil) }

相当于where("payment_status <> 'pending' OR payment_status IS NULL")

<强>更新 改为包括nil

答案 1 :(得分:1)

这不是因为Rails,而是因为它实际上是SQL的工作原理 !=意味着不同的东西,但仍然是某种东西。 NULL不是什么。

您可以看到this related issue

答案 2 :(得分:1)

在SQL中,表达式中的NULL值始终将表达式计算为false。理论上说,NULL值是未知的,而不仅仅是一个可以评估为0或者为false的空值。

例如,1 = NULL为false,但1 != NULL也为false。

所以在你的情况下,我可能会写:

where("payment_status != 'pending' or payment_status is null")