不为布尔值的Active Record:true

时间:2019-03-26 15:37:04

标签: ruby-on-rails ruby activerecord

我正在努力让自己围绕ActiveRecord查询。

我正在尝试在数据库中搜索ID为1..100,在其nil字段中具有某些内容(而不是:website且没有{{1 }}的true字段中。

这是我希望工作的查询:

duplicate_domain

我还尝试了以下基本相同的查询变体:GolfRetailer.where.not(website: nil, duplicate_domain: true).where(id: 1..100)

但是,尽管肯定有满足这些要求的记录,但是两者都返回一个空数组。

当我运行GolfRetailer.where.not(website: nil).where(id: 1..100, duplicate_domain: !true)时,我得到一个数组,而当我运行GolfRetailer.where.not(website: nil).where(id: 1..100)时,我也得到了一个数组,但是所有 do 记录都具有真实的plicate_domain标志,这不是我想要的。

我宁愿不搜索具有GolfRetailer.where.not(website: nil, duplicate_domain: nil).where(id: 1..100)的记录,因为这并不总是正确的(我可能尚未处理其域)。

为清楚起见,这是模型的架构。

duplicate_domain: nil

要使此查询有效,我缺少什么?

1 个答案:

答案 0 :(得分:5)

之所以会这样,是因为在SQL中,当您执行!= TRUE时,任何NULL值都不会包含在结果中。这是因为NULL值表示一个未知值,因此数据库不知道如何对未知值执行任何comparison operations,因此将其排除在外。

解决此问题的一种方法是使用IS DISTINCT FROM

GolfRetailer
  .where(id: 1..100)
  .where.not(website: nil)
  .where("duplicate_domain IS DISTINCT FROM ?", true)

正如其他人所提到的,您还应该问自己,是否真的不知道GolfRetailer是否具有duplicate_domain

如果所有GolfRetailer的{​​{1}}为duplicate_domain实际上表示它们没有一个(NULL),那么您应该考虑阻止{{1} }完全等于该列的值。

您可以通过在带有change_column database migration的列上添加NOT NULL约束来做到这一点。

要添加NOT NULL约束,您首先需要确保该列中的所有数据都具有非null值。

false

如果您的应用程序处于负载状态,则还应注意此类迁移可能具有的潜在性能-特别是如果您添加具有默认值的NOT NULL约束。

考虑使用类似Strong Migrations的工具来帮助查找可能导致生产前停机的数据库迁移。