Sql 有没有办法反转ActiveRecord::关系查询?
假设我们有以下几点:Sql 有没有办法反转ActiveRecord::关系查询?,sql,ruby-on-rails,ruby-on-rails-3,arel,Sql,Ruby On Rails,Ruby On Rails 3,Arel,假设我们有以下几点: irb> Post.where(:hidden => true).to_sql => "SELECT `posts`.* FROM `posts` WHERE posts.hidden = 1" 我们能从中得到一个反向SQL查询吗? 我要找的可能应该是这样的: irb> Post.where(:hidden => true).invert.to_sql => "SELECT `posts`.* FROM `posts` WHERE NO
irb> Post.where(:hidden => true).to_sql
=> "SELECT `posts`.* FROM `posts` WHERE posts.hidden = 1"
我们能从中得到一个反向SQL查询吗?
我要找的可能应该是这样的:
irb> Post.where(:hidden => true).invert.to_sql
=> "SELECT `posts`.* FROM `posts` WHERE NOT (posts.hidden = 1)"
用不同的语法,是的。例如:
posts = Post.scoped.table # or Arel::Table.new("posts")
posts.where(posts[:hidden].eq(true).not).to_sql
# => SELECT FROM `posts` WHERE NOT ((`posts`.`hidden` = 1))
通过将反向查询传递回ActiveRecord,我们可以进一步了解:
table = Post.arel_table
query = table[:hidden].eq(true).not # the inverted query, still ARel
Post.where(query) # plug it back into ActiveRecord
这将返回ActiveRecord对象,正如您通常期望的那样。当我查找具有“not true”条件(如false或nil)的记录时,我所做的是:
在rails 4中,有用于此目的的
not
后缀:
Post.where.not(hidden: true).to_sql
# => SELECT FROM `posts` WHERE `posts`.`hidden` != 1
在rails 3中,您可以使用。它提供了许多有用的特性。用它你可以写:
Post.where{ hidden != true }.to_sql
# => SELECT FROM `posts` WHERE `posts`.`hidden` != 1
最后,我们使用Rails 7的方法
invert_,其中
irb> Post.where(:hidden => true).invert_where.to_sql
"SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"hidden\" != 1"
请检查此项以了解更多详细信息。Hmm。对某人的评论
where(:hidden=>false)
进行错误的投票。这段代码不会生成OP所寻找的SQL类型。这与我所寻找的并不完全相同,但仍然是一个非常好的答案。您找到了其他方法吗?也许是更好的语法?答案对你有用吗?事实上,我认为这甚至是不可能的,因为我实际上要求的是反转和ActiveRecord::Relation对象,它可能有或可能没有多个连接和包含,这会使问题变得太复杂(我们应该在哪里反转,哪些不反转?)。我想我会把这件事留待答复。
irb> Post.where(:hidden => true).invert_where.to_sql
"SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"hidden\" != 1"