diff options
author | Rafael França <rafaelmfranca@gmail.com> | 2017-02-13 01:35:28 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-13 01:35:28 -0300 |
commit | efe121eab01d70c9da5747597d8ac6f526f2da4e (patch) | |
tree | d86d7dc258e24e0831a02fdcf27ecd5a080dea0d /activerecord/lib/active_record | |
parent | e0d0dc6ec1ea9f690f2f354381c0ddf1c3c2ab0b (diff) | |
parent | bbf1f152644177774710c52a230813e7d06935df (diff) | |
download | rails-efe121eab01d70c9da5747597d8ac6f526f2da4e.tar.gz rails-efe121eab01d70c9da5747597d8ac6f526f2da4e.tar.bz2 rails-efe121eab01d70c9da5747597d8ac6f526f2da4e.zip |
Merge pull request #27122 from kamipo/fix_unscope_with_subquery
Fix unscope with subquery
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/relation/where_clause.rb | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/relation/where_clause.rb b/activerecord/lib/active_record/relation/where_clause.rb index ef0d059d1c..417b24c7bb 100644 --- a/activerecord/lib/active_record/relation/where_clause.rb +++ b/activerecord/lib/active_record/relation/where_clause.rb @@ -25,10 +25,7 @@ module ActiveRecord end def except(*columns) - WhereClause.new( - predicates_except(columns), - binds_except(columns), - ) + WhereClause.new(*except_predicates_and_binds(columns)) end def or(other) @@ -134,20 +131,35 @@ module ActiveRecord end end - def predicates_except(columns) - predicates.reject do |node| - case node - when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual - subrelation = (node.left.kind_of?(Arel::Attributes::Attribute) ? node.left : node.right) - columns.include?(subrelation.name.to_s) + def except_predicates_and_binds(columns) + except_binds = [] + binds_index = 0 + + predicates = self.predicates.reject do |node| + except = \ + case node + when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual + binds_contains = node.grep(Arel::Nodes::BindParam).size + subrelation = (node.left.kind_of?(Arel::Attributes::Attribute) ? node.left : node.right) + columns.include?(subrelation.name.to_s) + end + + if except && binds_contains > 0 + (binds_index...(binds_index + binds_contains)).each do |i| + except_binds[i] = true + end + + binds_index += binds_contains end + + except end - end - def binds_except(columns) - binds.reject do |attr| - columns.include?(attr.name) + binds = self.binds.reject.with_index do |_, i| + except_binds[i] end + + [predicates, binds] end def predicates_with_wrapped_sql_literals |