如何在rails 4中编写具有多个条件的where.not查询

时间:2017-06-23 17:30:20

标签: ruby-on-rails-4 activerecord

我想表达的是:

Model.where("a IS NOT NULL `**`OR`**` b IS NOT NULL")

在Rails 4中,启用了where.not子句:

Model.where.not(a: nil, b: nil)

但是,此表达式等于

Model.where("a IS NOT NULL `**`AND`**` b IS NOT NULL")

我该如何表达

"a IS NOT NULL `**`OR`**` b IS NOT NULL"
带有where.not子句的

3 个答案:

答案 0 :(得分:6)

您可以使用where.nota属性b尝试创建查询:

query = Model.where.not(a: nil, b: nil)

然后通过传递inject运算符,在之前创建的查询的where值中使用or

Model.where(query.where_values.inject(:or))

这将为您提供如下查询:

SELECT "model".* FROM "model" WHERE ("model"."a" IS NOT NULL OR "model"."b" IS NOT NULL)

尽管第一个使用AND运算符为您提供了一些内容,例如:

SELECT "model".* FROM "model" WHERE ("model"."a" IS NOT NULL) AND ("model"."b" IS NOT NULL)

答案 1 :(得分:4)

在导轨4中没有导轨方式。

您可以尝试rails_or,它会为您提供oror_not方法:

Model.where.not(a: nil).or_not(b: nil)

或者升级到rails 5并将查询写为:

Model.where.not(a: nil).or(Model.where.not(b: nil))

答案 2 :(得分:0)

重要提示:Rails 6.1更改具有多个属性的where.not的行为!


直到Rails 5.2-NOR(NOT(A)和NOT(B))。

在Rails 5.2之前,如果我们将where.not与多个属性一起使用,它将在查询的NOR (NOT(A) AND NOT(B))子句中应用逻辑WHERE

Post.where.not(source_type: "Feed", source_id: 100).to_sql

# => SELECT "posts".* FROM "posts" WHERE "posts"."source_type" != 'Feed' AND "posts"."source_id" != 100

使用弃用的第6条-NOR(NOT(A)和NOT(B))。

Rails 6添加了弃用警告。

Post.where.not(source_type: "Feed", source_id: 100)

DEPRECATION WARNING: NOT conditions will no longer behave as NOR in Rails 6.1.
To continue using NOR conditions, NOT each conditions manually 
(`.where.not(:source_type => ...).where.not(:source_id => ...)`).

Rails 6.1+-NAND(NOT(A)或NOT(B))。

Rails 6.1+将where.not的工作方式更改为NAND (NOT(A) OR NOT(B))

Post.where.not(source_type: "Feed", source_id: 100).to_sql

# => SELECT "posts".* FROM "posts" WHERE ("posts"."source_type" != 'Feed' OR "posts"."source_id" != 100)

来源: