ActiveRecord where.not不工作/奇怪的行为

用户has_many计划。 我正在尝试查找没有状态为“已取消”的所有用户的ID。 很想知道下面的行为是什么。

对于上下文,应该返回的是:

 User.select { |u| u.plans.select { |p| p.status != "canceled" }.count > 0 }.map(&:id) # => [27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63] 

这是我得到的:

 # statement 1 User.joins(:plans).where.not("plans.status" => "canceled").map(&:id) # User Load (0.3ms) SELECT "users".* FROM "users" INNER JOIN "plans" ON "plans"."user_id" = "users"."id" WHERE ("plans"."status" != 'canceled') # => [44] # statement 2 User.joins(:plans).where("plans.status != ?", "canceled").map(&:id) # User Load (0.3ms) SELECT "users".* FROM "users" INNER JOIN "plans" ON "plans"."user_id" = "users"."id" WHERE (plans.status != 'canceled') # => [44] # statement 3 User.joins(:plans).where("plans.status == ?", nil).map(&:id) # User Load (0.3ms) SELECT "users".* FROM "users" INNER JOIN "plans" ON "plans"."user_id" = "users"."id" WHERE (plans.status == NULL) # => [] # statement 4 User.joins(:plans).where("plans.status" => nil).map(&:id) # User Load (0.7ms) SELECT "users".* FROM "users" INNER JOIN "plans" ON "plans"."user_id" = "users"."id" WHERE "plans"."status" IS NULL # => [27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 41, 44, 42, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 61, 60, 62, 63] 

问题:

  1. 为什么语句3和4没有返回相同的结果?
  2. 为什么语句1和2(幸运的是它们是相同的并且返回相同的结果)没有返回与语句4相同的结果? 对于上下文,我宁愿不搜索nil ,而是"canceled" 。 我可以确认所有计划的状态都是nil"canceled"

每次请求更新

 # plan with nil status Plan.where(status: nil).first # =>  # plan with canceled status Plan.where(status: "canceled").first # =>  

对问题1的回答:

你错过了在条件sql中,替换条件的参数被替换的概念? 没有比较。 所以,将double ==替换为=

 User.joins(:plans).where("plans.status = ?", nil).map(&:id)