不应该`where.not(field:"something")`include`where(field:nil)`?

Zig*_*ggy 4 arel ruby-on-rails-4

也许我会发疯,或者只是需要休息,但是在我的rails控制台Order.where(state: nil).count返回1010,但Order.where.not(state: "pending").count返回0...如果订单的状态为nil,那么它不是"挂起",所以我希望返回的集合not(state: "pending")包括设定where(state: nil).

这样做不行吗?如果没有,是否会以不同的方式工作?

编辑:更多信息!当我去另一个数据库,其中一些记录的状态不是nil,然后我运行Order.where.not(state: "pending").count我得到一堆订单,其中没有一个是"待定",但也没有一个是零.似乎where.not隐含and not nil地在查询中添加了一个?

编辑:绝望中,我变成了更黑暗的精神.

# look into another shop, that has records
o = Order.where(shop_id: 2)

# summon dread spirits
t = Order.arel_table[:state]

o.where(t.eq(nil).or(t.eq("pending").not)).count

=> 1569

o.where(t.eq(nil)).count

=> 1471
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,我得到的98条记录的状态既不是nil也不是"pending",我得到状态为nil的所有记录.我真的很想知道为什么我不能说出来where.not("pending")也有同样的效果.如果有可能我可以调用的选项?喜欢,where.not("pending", include_nil: true)

编辑:根据@Filip Bartuzi的评论要求

Order.where.not(state: "pending").to_sql

=> "SELECT \"orders\".* FROM \"orders\"  WHERE \"orders\".\"shop_id\" = 2 AND (\"orders\".\"state\" != 'pending')"

Orders.where(state: nil).to_sql

=> "SELECT \"orders\".* FROM \"orders\"  WHERE \"orders\".\"shop_id\" = 2 AND \"orders\".\"state\" IS NULL"
Run Code Online (Sandbox Code Playgroud)

Fil*_*uzi 6

Order.where.not(state: "pending").to_sql 产生:

=> "SELECT \"orders\".* FROM \"orders\" WHERE \"orders\".\"shop_id\" = 2 AND (\"orders\".\"state\" != 'pending')"

它将返回VALUES的所有记录,这些记录不是"待定".当你设置pendingnil(就像Order.first.update! state: nil它分配NULL数据库.

NULL不会在SQL中解释为值,因此它不会包含在SELECT响应中

所以答案是:where.not(field: “something”)不包括where(field: nil)!

您可以在这里查看它的工作原理:

http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all

转到类别表并首先执行

UPDATE Categories
SET CategoryName = NULL
WHERE CategoryName = 'Beverages'
Run Code Online (Sandbox Code Playgroud)

所以现在我们有Count 8的类别,其中一个NULL列在列上CategoryName

现在执行:

SELECT CategoryName FROM Categories
WHERE CategoryName != 'Condiments'
Run Code Online (Sandbox Code Playgroud)

当你看到返回的6条记录时(所以它跳过一条NULL)