【问题标题】:ActiveRecord where.not is not working/ weird behaviorActiveRecord where.not 不工作/奇怪的行为
【发布时间】:2015-07-27 03:42:58
【问题描述】:

用户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 id: 1, zipcode: "94282", selected_plan: 1, meal_type: "Chef's choice (mixed)", most_favorite: "", least_favorite: "", allergies: "", start_date: "2015-05-27 00:00:00", delivery_address: "d", delivery_instructions: "", phone1: "10", phone2: "222", phone3: "2222", agree_tos: true, user_id: 20, created_at: "2015-05-24 05:18:40", updated_at: "2015-06-21 04:54:31", stripe_subscription_id: nil, stripe_invoice_number: nil, cancel_reason: nil, cancel_reason_other: nil, nps: nil, nps_open: nil, cancel_open: nil, status: nil, referred_by_code: nil>

# plan with canceled status
Plan.where(status: "canceled").first
# => <Plan id: 20, zipcode: "12345", selected_plan: 5, meal_type: "Meat (with veggies)", most_favorite: "", least_favorite: "", allergies: "", start_date: "2015-06-08 00:00:00", delivery_address: "asdf", delivery_instructions: "", phone1: "333", phone2: "333", phone3: "3333", agree_tos: true, user_id: 38, created_at: "2015-06-01 21:39:54", updated_at: "2015-06-23 06:23:10", stripe_subscription_id: "sub_6OKkJoNx2u8ZXZ", stripe_invoice_number: 0, cancel_reason: nil, cancel_reason_other: "", nps: 6, nps_open: "", cancel_open: "", status: "canceled", referred_by_code: nil> 

【问题讨论】:

  • SQL 的正确语法是一个等号,而不是两个
  • @LoganSerman 好像没关系,要么一两个= 返回空白
  • 对于 null 你需要使用 IS NULL
  • 嗯,这很公平。但我真正想做的是尝试让语句 1 和 2 工作。有什么想法?
  • 你能发布你的分贝内容,每一个状态为nilcancelled吗?

标签: sql ruby-on-rails ruby-on-rails-4 activerecord


【解决方案1】:

问题 1 的答案:

您错过了在条件 sql 中,条件后面的参数被替换为 ? 而不是比较的概念。因此,将双 == 替换为 =

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

【讨论】:

  • 好的(抱歉休息,需要执行紧急任务),我在上面添加了查询,在这个问题上我真的需要语句 1 或 2 来工作,有什么想法吗?你上面的回答只会给我一个[],这也不是我想要的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
  • 2013-08-08
  • 1970-01-01
  • 2021-05-31
  • 2011-11-25
相关资源
最近更新 更多