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

Kin*_*han 6 activerecord ruby-on-rails-4

我要表达的是:.where.notwhere.notwhere.not

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

但是,这个表达式等于.where.notwhere.notwhere.not

如何用条款表达?where.notwhere.notwhere.notwhere.not

Mar*_*n13 14

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


直至 Rails 5.2 - NOR(NOT(A) AND NOT(B))。

直到 Rails 5.2,如果我们使用where.not多个属性,它会应用查询的逻辑NOR (NOT(A) AND NOT(B))in子句。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
Run Code Online (Sandbox Code Playgroud)

Rails 6 - NOR ( NOT(A) AND 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 => ...)`).
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

资料来源:

  • 这并不能回答问题 (2认同)
  • 我在 Rails 6.1 上没有看到“OR”: `> User.where.not(email: "test@test.com", name: "test name").to_sql` `=> "SELECT \"users\ ".* FROM \"users\" WHERE NOT (\"users\".\"email\" = 'test@test.com' AND \"users\".\"name\" = '测试名称')" ` (2认同)

Seb*_*lma 8

如你有尝试过,您可以创建您的查询where.notab属性:

query = Model.where.not(a: nil, b: nil)
Run Code Online (Sandbox Code Playgroud)

然后通过传递运算符来使用之前创建的查询injectwhereor:

Model.where(query.where_values.inject(:or))
Run Code Online (Sandbox Code Playgroud)

这将为您提供如下查询:

SELECT "model".*
FROM "model"
WHERE (
  "model"."a" IS NOT NULL OR
  "model"."b" IS NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

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

SELECT "model".*
FROM "model"
WHERE ("model"."a" IS NOT NULL) AND
      ("model"."b" IS NOT NULL)
Run Code Online (Sandbox Code Playgroud)


khi*_*eoy 5

Rails 4中没有实现此目的的方法。

您可以尝试使用rails_or给您oror_not方法:

Model.where.not(a: nil).or_not(b: nil)
Run Code Online (Sandbox Code Playgroud)

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

Model.where.not(a: nil).or(Model.where.not(b: nil))
Run Code Online (Sandbox Code Playgroud)