ActiveRecord的:但.where.not(富:“巴”):可与。凡(“巴”富)成功地查询不返回正确的结果

ActiveRecord的:但.where.not(富:“巴”):可与。凡(“巴”富)成功地查询不返回正确的结果

问题描述:

我有一个查询建立像这样:ActiveRecord的:但.where.not(富:“巴”):可与。凡(“巴”富)成功地查询不返回正确的结果

@events = current_organization.events.order(started_at: :asc) 

我想查询所有那些status不是"canceled"的事件。但是,当我使用这样的查询时:

current_organization.events.order(started_at: :asc).where.not(status: "canceled") 

它不返回任何内容。然而,仅仅为了试验的缘故,我尝试过:

@events = current_organization.events.where(status: "canceled") 

它成功返回取消的事件。由于某些原因,反转不起作用。这是什么原因?我只能用where(status: nil)找到,但这真的很不直观。

+1

尝试检查#to_sql输出。这有助于调试sql语句 current_organization.events.order(started_at::asc).where.not(status:“canceled”)。to_sql –

+0

您是否在事件模型中设置了'default_scope'? – mysmallidea

+0

@MickeySheu,这里有不同的输出 '@events = current_organization.events.order(started_at:升序)。凡(状态: “取消”)。to_sql' '=> “SELECT \” 事件\” 。“FROM \”events \“WHERE \”events \“。\”organization_id \“= 1 AND \”events \“。\”status \“='canceled'ORDER BY \”events \“。\”started_at \ “ASC”' '@events = current_organization.events.order(started_at::asc).where.not(status:“canceled”)to_sql' '=>“SELECT \”events \“。* FROM \“events \”WHERE \“events \”。\“organization_id \”= 1 AND(\“events \”。\“status \”!='cancelled')ORDER BY \“events \”。\“started_at \ “ASC”' – Antonio

此更新你的问题:

编辑:我唯一的工作,我周围能找到的只是用where(status: nil)但是这真的不直观。

很重要。这告诉我你的status列允许有NULL的值,并且你有NULL的值。

那些NULL与ActiveRecord的where.not的有点差实施相结合是你的麻烦的原因。如果我们看一下SQL由生产:

where.not(status: "canceled") 

我们看到:

("events"."status" != 'canceled') 

但在SQL,既x = nullx <> null都计算为null所有x(包括当x本身null )和null在SQL中不是一个真值;这意味着x <> y是不完全的x = ynull s的参与正好相反:如果行的statusnull则既不where status = 'canceled'也不where status != 'canceled'会发现它。

每当null s的参与,你只能用对待null他们的方式,你希望运营商合作:is nullis not nullis distinct fromis not distinct from,...

status列允许null小号听起来很奇怪我并修复,这将使问题消失:

  1. 添加迁移将所有null状态更改为更好的工作。 A status is null列表示行/模型根本没有状态,这很奇怪,所以给他们一个真实的状态代码。
  2. 添加一个迁移让你的statusnot null这样你就再也不用担心null的状态。
  3. 更新您的模型的验证,不允许status.nil?发生。

一般情况下,除非你能够确定的是,null奇妆感,你准备以应对SQL如何null作品不使用空列的任何地方。

+0

将设置一个默认值到我的列是相同的,使列不为空? – Antonio

+0

不是真的,但可以将其设置为“不为空”并添加默认值。不过,你确实希望列不是空的,否则'null'将会在那里结束并导致问题。 –

+0

你的答案非常擅长解释SQL如何处理null。我继续前进,对该专栏做了必要的修改,我认为这不会给我一个问题。谢谢。 – Antonio