diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-04-23 16:15:30 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-23 16:15:30 +0900 |
commit | 9d1f9b9a0c344dd8f4b6b321a3fe8e9f500f841c (patch) | |
tree | 0045ff846a25aba282579fa508c15c5e557a5e4d /activerecord/lib/active_record/relation | |
parent | afc17e5ea21759df5b9ef2ac9421b02154a09b9b (diff) | |
parent | 12a9664ff60f0e2712fd1f79f8dbec06e2f004a2 (diff) | |
download | rails-9d1f9b9a0c344dd8f4b6b321a3fe8e9f500f841c.tar.gz rails-9d1f9b9a0c344dd8f4b6b321a3fe8e9f500f841c.tar.bz2 rails-9d1f9b9a0c344dd8f4b6b321a3fe8e9f500f841c.zip |
Merge pull request #36029 from kamipo/deprecate_where_not
Deprecate `where.not` working as NOR and will be changed to NAND in Rails 6.1
Diffstat (limited to 'activerecord/lib/active_record/relation')
-rw-r--r-- | activerecord/lib/active_record/relation/query_methods.rb | 21 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/where_clause.rb | 14 |
2 files changed, 26 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 5d3cea6741..f30428d0a5 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -41,18 +41,31 @@ module ActiveRecord # # User.where.not(name: %w(Ko1 Nobu)) # # SELECT * FROM users WHERE name NOT IN ('Ko1', 'Nobu') - # - # User.where.not(name: "Jon", role: "admin") - # # SELECT * FROM users WHERE name != 'Jon' AND role != 'admin' def not(opts, *rest) opts = sanitize_forbidden_attributes(opts) where_clause = @scope.send(:where_clause_factory).build(opts, rest) @scope.references!(PredicateBuilder.references(opts)) if Hash === opts - @scope.where_clause += where_clause.invert + + if not_behaves_as_nor?(opts) + ActiveSupport::Deprecation.warn(<<~MSG.squish) + NOT conditions will no longer behave as NOR in Rails 6.1. + To continue using NOR conditions, NOT each conditions manually + (`#{ opts.keys.map { |key| ".where.not(#{key.inspect} => ...)" }.join }`). + MSG + @scope.where_clause += where_clause.invert(:nor) + else + @scope.where_clause += where_clause.invert + end + @scope end + + private + def not_behaves_as_nor?(opts) + opts.is_a?(Hash) && opts.size > 1 + end end FROZEN_EMPTY_ARRAY = [].freeze diff --git a/activerecord/lib/active_record/relation/where_clause.rb b/activerecord/lib/active_record/relation/where_clause.rb index 47728aac30..b91b135867 100644 --- a/activerecord/lib/active_record/relation/where_clause.rb +++ b/activerecord/lib/active_record/relation/where_clause.rb @@ -70,7 +70,15 @@ module ActiveRecord predicates == other.predicates end - def invert + def invert(as = :nand) + if predicates.size == 1 + inverted_predicates = [ invert_predicate(predicates.first) ] + elsif as == :nor + inverted_predicates = predicates.map { |node| invert_predicate(node) } + else + inverted_predicates = [ Arel::Nodes::Not.new(ast) ] + end + WhereClause.new(inverted_predicates) end @@ -115,10 +123,6 @@ module ActiveRecord node.respond_to?(:operator) && node.operator == :== end - def inverted_predicates - predicates.map { |node| invert_predicate(node) } - end - def invert_predicate(node) case node when NilClass |