activerecord 5.2.1 → 5.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +228 -0
 - data/lib/active_record/association_relation.rb +3 -3
 - data/lib/active_record/associations/association.rb +8 -0
 - data/lib/active_record/associations/builder/collection_association.rb +2 -2
 - data/lib/active_record/associations/collection_association.rb +9 -8
 - data/lib/active_record/associations/collection_proxy.rb +8 -34
 - data/lib/active_record/associations/has_many_association.rb +9 -0
 - data/lib/active_record/associations/has_many_through_association.rb +28 -11
 - data/lib/active_record/associations/join_dependency/join_association.rb +28 -7
 - data/lib/active_record/associations/preloader.rb +1 -1
 - data/lib/active_record/attribute_methods/dirty.rb +13 -8
 - data/lib/active_record/autosave_association.rb +25 -11
 - data/lib/active_record/callbacks.rb +1 -1
 - data/lib/active_record/collection_cache_key.rb +2 -2
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +36 -11
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +19 -6
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -3
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +3 -1
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +18 -8
 - data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +7 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +36 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +10 -24
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +9 -1
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +4 -0
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +3 -3
 - data/lib/active_record/core.rb +2 -1
 - data/lib/active_record/enum.rb +1 -0
 - data/lib/active_record/errors.rb +18 -12
 - data/lib/active_record/gem_version.rb +1 -1
 - data/lib/active_record/migration.rb +1 -1
 - data/lib/active_record/migration/compatibility.rb +15 -15
 - data/lib/active_record/model_schema.rb +1 -1
 - data/lib/active_record/persistence.rb +5 -4
 - data/lib/active_record/querying.rb +1 -1
 - data/lib/active_record/railtie.rb +1 -3
 - data/lib/active_record/reflection.rb +10 -14
 - data/lib/active_record/relation.rb +26 -7
 - data/lib/active_record/relation/calculations.rb +16 -12
 - data/lib/active_record/relation/delegation.rb +30 -0
 - data/lib/active_record/relation/finder_methods.rb +8 -4
 - data/lib/active_record/relation/merger.rb +8 -5
 - data/lib/active_record/relation/predicate_builder.rb +14 -9
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
 - data/lib/active_record/relation/query_attribute.rb +5 -3
 - data/lib/active_record/relation/query_methods.rb +35 -10
 - data/lib/active_record/relation/spawn_methods.rb +1 -1
 - data/lib/active_record/scoping/default.rb +2 -2
 - data/lib/active_record/scoping/named.rb +2 -0
 - data/lib/active_record/statement_cache.rb +2 -2
 - data/lib/active_record/tasks/database_tasks.rb +1 -1
 - data/lib/active_record/transactions.rb +1 -1
 - metadata +9 -10
 
| 
         @@ -375,7 +375,7 @@ module ActiveRecord 
     | 
|
| 
       375 
375 
     | 
    
         
             
                  # default values when instantiating the Active Record object for this table.
         
     | 
| 
       376 
376 
     | 
    
         
             
                  def column_defaults
         
     | 
| 
       377 
377 
     | 
    
         
             
                    load_schema
         
     | 
| 
       378 
     | 
    
         
            -
                    @column_defaults ||= _default_attributes.to_hash
         
     | 
| 
      
 378 
     | 
    
         
            +
                    @column_defaults ||= _default_attributes.deep_dup.to_hash
         
     | 
| 
       379 
379 
     | 
    
         
             
                  end
         
     | 
| 
       380 
380 
     | 
    
         | 
| 
       381 
381 
     | 
    
         
             
                  def _default_attributes # :nodoc:
         
     | 
| 
         @@ -473,15 +473,16 @@ module ActiveRecord 
     | 
|
| 
       473 
473 
     | 
    
         
             
                    verify_readonly_attribute(key.to_s)
         
     | 
| 
       474 
474 
     | 
    
         
             
                  end
         
     | 
| 
       475 
475 
     | 
    
         | 
| 
      
 476 
     | 
    
         
            +
                  id_in_database = self.id_in_database
         
     | 
| 
      
 477 
     | 
    
         
            +
                  attributes.each do |k, v|
         
     | 
| 
      
 478 
     | 
    
         
            +
                    write_attribute_without_type_cast(k, v)
         
     | 
| 
      
 479 
     | 
    
         
            +
                  end
         
     | 
| 
      
 480 
     | 
    
         
            +
             
     | 
| 
       476 
481 
     | 
    
         
             
                  affected_rows = self.class._update_record(
         
     | 
| 
       477 
482 
     | 
    
         
             
                    attributes,
         
     | 
| 
       478 
483 
     | 
    
         
             
                    self.class.primary_key => id_in_database
         
     | 
| 
       479 
484 
     | 
    
         
             
                  )
         
     | 
| 
       480 
485 
     | 
    
         | 
| 
       481 
     | 
    
         
            -
                  attributes.each do |k, v|
         
     | 
| 
       482 
     | 
    
         
            -
                    write_attribute_without_type_cast(k, v)
         
     | 
| 
       483 
     | 
    
         
            -
                  end
         
     | 
| 
       484 
     | 
    
         
            -
             
     | 
| 
       485 
486 
     | 
    
         
             
                  affected_rows == 1
         
     | 
| 
       486 
487 
     | 
    
         
             
                end
         
     | 
| 
       487 
488 
     | 
    
         | 
| 
         @@ -40,7 +40,7 @@ module ActiveRecord 
     | 
|
| 
       40 
40 
     | 
    
         
             
                def find_by_sql(sql, binds = [], preparable: nil, &block)
         
     | 
| 
       41 
41 
     | 
    
         
             
                  result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
         
     | 
| 
       42 
42 
     | 
    
         
             
                  column_types = result_set.column_types.dup
         
     | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
      
 43 
     | 
    
         
            +
                  attribute_types.each_key { |k| column_types.delete k }
         
     | 
| 
       44 
44 
     | 
    
         
             
                  message_bus = ActiveSupport::Notifications.instrumenter
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
                  payload = {
         
     | 
| 
         @@ -169,9 +169,7 @@ end_warning 
     | 
|
| 
       169 
169 
     | 
    
         
             
                end
         
     | 
| 
       170 
170 
     | 
    
         | 
| 
       171 
171 
     | 
    
         
             
                initializer "active_record.set_executor_hooks" do
         
     | 
| 
       172 
     | 
    
         
            -
                   
     | 
| 
       173 
     | 
    
         
            -
                    ActiveRecord::QueryCache.install_executor_hooks
         
     | 
| 
       174 
     | 
    
         
            -
                  end
         
     | 
| 
      
 172 
     | 
    
         
            +
                  ActiveRecord::QueryCache.install_executor_hooks
         
     | 
| 
       175 
173 
     | 
    
         
             
                end
         
     | 
| 
       176 
174 
     | 
    
         | 
| 
       177 
175 
     | 
    
         
             
                initializer "active_record.add_watchable_files" do |app|
         
     | 
| 
         @@ -174,28 +174,24 @@ module ActiveRecord 
     | 
|
| 
       174 
174 
     | 
    
         
             
                    scope ? [scope] : []
         
     | 
| 
       175 
175 
     | 
    
         
             
                  end
         
     | 
| 
       176 
176 
     | 
    
         | 
| 
       177 
     | 
    
         
            -
                  def  
     | 
| 
       178 
     | 
    
         
            -
                    key         = join_keys.key
         
     | 
| 
       179 
     | 
    
         
            -
                    foreign_key = join_keys.foreign_key
         
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
                    constraint = table[key].eq(foreign_table[foreign_key])
         
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
                    if klass.finder_needs_type_condition?
         
     | 
| 
       184 
     | 
    
         
            -
                      table.create_and([constraint, klass.send(:type_condition, table)])
         
     | 
| 
       185 
     | 
    
         
            -
                    else
         
     | 
| 
       186 
     | 
    
         
            -
                      constraint
         
     | 
| 
       187 
     | 
    
         
            -
                    end
         
     | 
| 
       188 
     | 
    
         
            -
                  end
         
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
                  def join_scope(table, foreign_klass)
         
     | 
| 
      
 177 
     | 
    
         
            +
                  def join_scope(table, foreign_table, foreign_klass)
         
     | 
| 
       191 
178 
     | 
    
         
             
                    predicate_builder = predicate_builder(table)
         
     | 
| 
       192 
179 
     | 
    
         
             
                    scope_chain_items = join_scopes(table, predicate_builder)
         
     | 
| 
       193 
180 
     | 
    
         
             
                    klass_scope       = klass_join_scope(table, predicate_builder)
         
     | 
| 
       194 
181 
     | 
    
         | 
| 
      
 182 
     | 
    
         
            +
                    key         = join_keys.key
         
     | 
| 
      
 183 
     | 
    
         
            +
                    foreign_key = join_keys.foreign_key
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                    klass_scope.where!(table[key].eq(foreign_table[foreign_key]))
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
       195 
187 
     | 
    
         
             
                    if type
         
     | 
| 
       196 
188 
     | 
    
         
             
                      klass_scope.where!(type => foreign_klass.polymorphic_name)
         
     | 
| 
       197 
189 
     | 
    
         
             
                    end
         
     | 
| 
       198 
190 
     | 
    
         | 
| 
      
 191 
     | 
    
         
            +
                    if klass.finder_needs_type_condition?
         
     | 
| 
      
 192 
     | 
    
         
            +
                      klass_scope.where!(klass.send(:type_condition, table))
         
     | 
| 
      
 193 
     | 
    
         
            +
                    end
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
       199 
195 
     | 
    
         
             
                    scope_chain_items.inject(klass_scope, &:merge!)
         
     | 
| 
       200 
196 
     | 
    
         
             
                  end
         
     | 
| 
       201 
197 
     | 
    
         | 
| 
         @@ -54,7 +54,7 @@ module ActiveRecord 
     | 
|
| 
       54 
54 
     | 
    
         
             
                #   user = users.new { |user| user.name = 'Oscar' }
         
     | 
| 
       55 
55 
     | 
    
         
             
                #   user.name # => Oscar
         
     | 
| 
       56 
56 
     | 
    
         
             
                def new(attributes = nil, &block)
         
     | 
| 
       57 
     | 
    
         
            -
                  scoping { klass.new( 
     | 
| 
      
 57 
     | 
    
         
            +
                  scoping { klass.new(values_for_create(attributes), &block) }
         
     | 
| 
       58 
58 
     | 
    
         
             
                end
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
                alias build new
         
     | 
| 
         @@ -82,7 +82,7 @@ module ActiveRecord 
     | 
|
| 
       82 
82 
     | 
    
         
             
                  if attributes.is_a?(Array)
         
     | 
| 
       83 
83 
     | 
    
         
             
                    attributes.collect { |attr| create(attr, &block) }
         
     | 
| 
       84 
84 
     | 
    
         
             
                  else
         
     | 
| 
       85 
     | 
    
         
            -
                    scoping { klass.create( 
     | 
| 
      
 85 
     | 
    
         
            +
                    scoping { klass.create(values_for_create(attributes), &block) }
         
     | 
| 
       86 
86 
     | 
    
         
             
                  end
         
     | 
| 
       87 
87 
     | 
    
         
             
                end
         
     | 
| 
       88 
88 
     | 
    
         | 
| 
         @@ -96,7 +96,7 @@ module ActiveRecord 
     | 
|
| 
       96 
96 
     | 
    
         
             
                  if attributes.is_a?(Array)
         
     | 
| 
       97 
97 
     | 
    
         
             
                    attributes.collect { |attr| create!(attr, &block) }
         
     | 
| 
       98 
98 
     | 
    
         
             
                  else
         
     | 
| 
       99 
     | 
    
         
            -
                    scoping { klass.create!( 
     | 
| 
      
 99 
     | 
    
         
            +
                    scoping { klass.create!(values_for_create(attributes), &block) }
         
     | 
| 
       100 
100 
     | 
    
         
             
                  end
         
     | 
| 
       101 
101 
     | 
    
         
             
                end
         
     | 
| 
       102 
102 
     | 
    
         | 
| 
         @@ -337,6 +337,14 @@ module ActiveRecord 
     | 
|
| 
       337 
337 
     | 
    
         
             
                  @klass.connection.update stmt, "#{@klass} Update All"
         
     | 
| 
       338 
338 
     | 
    
         
             
                end
         
     | 
| 
       339 
339 
     | 
    
         | 
| 
      
 340 
     | 
    
         
            +
                def update(id = :all, attributes) # :nodoc:
         
     | 
| 
      
 341 
     | 
    
         
            +
                  if id == :all
         
     | 
| 
      
 342 
     | 
    
         
            +
                    each { |record| record.update(attributes) }
         
     | 
| 
      
 343 
     | 
    
         
            +
                  else
         
     | 
| 
      
 344 
     | 
    
         
            +
                    klass.update(id, attributes)
         
     | 
| 
      
 345 
     | 
    
         
            +
                  end
         
     | 
| 
      
 346 
     | 
    
         
            +
                end
         
     | 
| 
      
 347 
     | 
    
         
            +
             
     | 
| 
       340 
348 
     | 
    
         
             
                # Destroys the records by instantiating each
         
     | 
| 
       341 
349 
     | 
    
         
             
                # record and calling its {#destroy}[rdoc-ref:Persistence#destroy] method.
         
     | 
| 
       342 
350 
     | 
    
         
             
                # Each object's callbacks are executed (including <tt>:dependent</tt> association options).
         
     | 
| 
         @@ -456,10 +464,8 @@ module ActiveRecord 
     | 
|
| 
       456 
464 
     | 
    
         
             
                  where_clause.to_h(relation_table_name)
         
     | 
| 
       457 
465 
     | 
    
         
             
                end
         
     | 
| 
       458 
466 
     | 
    
         | 
| 
       459 
     | 
    
         
            -
                def scope_for_create 
     | 
| 
       460 
     | 
    
         
            -
                   
     | 
| 
       461 
     | 
    
         
            -
                  scope.merge!(attributes) if attributes
         
     | 
| 
       462 
     | 
    
         
            -
                  scope
         
     | 
| 
      
 467 
     | 
    
         
            +
                def scope_for_create
         
     | 
| 
      
 468 
     | 
    
         
            +
                  where_values_hash.merge!(create_with_value.stringify_keys)
         
     | 
| 
       463 
469 
     | 
    
         
             
                end
         
     | 
| 
       464 
470 
     | 
    
         | 
| 
       465 
471 
     | 
    
         
             
                # Returns true if relation needs eager loading.
         
     | 
| 
         @@ -606,5 +612,18 @@ module ActiveRecord 
     | 
|
| 
       606 
612 
     | 
    
         
             
                    # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries
         
     | 
| 
       607 
613 
     | 
    
         
             
                    string.scan(/([a-zA-Z_][.\w]+).?\./).flatten.map(&:downcase).uniq - ["raw_sql_"]
         
     | 
| 
       608 
614 
     | 
    
         
             
                  end
         
     | 
| 
      
 615 
     | 
    
         
            +
             
     | 
| 
      
 616 
     | 
    
         
            +
                  def values_for_create(attributes = nil)
         
     | 
| 
      
 617 
     | 
    
         
            +
                    result = attributes ? where_values_hash.merge!(attributes) : where_values_hash
         
     | 
| 
      
 618 
     | 
    
         
            +
             
     | 
| 
      
 619 
     | 
    
         
            +
                    # NOTE: if there are same keys in both create_with and result, create_with should be used.
         
     | 
| 
      
 620 
     | 
    
         
            +
                    # This is to make sure nested attributes don't get passed to the klass.new,
         
     | 
| 
      
 621 
     | 
    
         
            +
                    # while keeping the precedence of the duplicate keys in create_with.
         
     | 
| 
      
 622 
     | 
    
         
            +
                    create_with_value.stringify_keys.each do |k, v|
         
     | 
| 
      
 623 
     | 
    
         
            +
                      result[k] = v if result.key?(k)
         
     | 
| 
      
 624 
     | 
    
         
            +
                    end
         
     | 
| 
      
 625 
     | 
    
         
            +
             
     | 
| 
      
 626 
     | 
    
         
            +
                    result
         
     | 
| 
      
 627 
     | 
    
         
            +
                  end
         
     | 
| 
       609 
628 
     | 
    
         
             
              end
         
     | 
| 
       610 
629 
     | 
    
         
             
            end
         
     | 
| 
         @@ -133,11 +133,12 @@ module ActiveRecord 
     | 
|
| 
       133 
133 
     | 
    
         
             
                    relation = apply_join_dependency
         
     | 
| 
       134 
134 
     | 
    
         | 
| 
       135 
135 
     | 
    
         
             
                    if operation.to_s.downcase == "count"
         
     | 
| 
       136 
     | 
    
         
            -
                       
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
                        relation.order_values = []
         
     | 
| 
      
 136 
     | 
    
         
            +
                      unless distinct_value || distinct_select?(column_name || select_for_count)
         
     | 
| 
      
 137 
     | 
    
         
            +
                        relation.distinct!
         
     | 
| 
      
 138 
     | 
    
         
            +
                        relation.select_values = [ klass.primary_key || table[Arel.star] ]
         
     | 
| 
       140 
139 
     | 
    
         
             
                      end
         
     | 
| 
      
 140 
     | 
    
         
            +
                      # PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT
         
     | 
| 
      
 141 
     | 
    
         
            +
                      relation.order_values = []
         
     | 
| 
       141 
142 
     | 
    
         
             
                    end
         
     | 
| 
       142 
143 
     | 
    
         | 
| 
       143 
144 
     | 
    
         
             
                    relation.calculate(operation, column_name)
         
     | 
| 
         @@ -190,11 +191,9 @@ module ActiveRecord 
     | 
|
| 
       190 
191 
     | 
    
         
             
                    relation = apply_join_dependency
         
     | 
| 
       191 
192 
     | 
    
         
             
                    relation.pluck(*column_names)
         
     | 
| 
       192 
193 
     | 
    
         
             
                  else
         
     | 
| 
       193 
     | 
    
         
            -
                    enforce_raw_sql_whitelist(column_names)
         
     | 
| 
      
 194 
     | 
    
         
            +
                    klass.enforce_raw_sql_whitelist(column_names)
         
     | 
| 
       194 
195 
     | 
    
         
             
                    relation = spawn
         
     | 
| 
       195 
     | 
    
         
            -
                    relation.select_values = column_names 
     | 
| 
       196 
     | 
    
         
            -
                      @klass.has_attribute?(cn) || @klass.attribute_alias?(cn) ? arel_attribute(cn) : cn
         
     | 
| 
       197 
     | 
    
         
            -
                    }
         
     | 
| 
      
 196 
     | 
    
         
            +
                    relation.select_values = column_names
         
     | 
| 
       198 
197 
     | 
    
         
             
                    result = skip_query_cache_if_necessary { klass.connection.select_all(relation.arel, nil) }
         
     | 
| 
       199 
198 
     | 
    
         
             
                    result.cast_values(klass.attribute_types)
         
     | 
| 
       200 
199 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -209,7 +208,6 @@ module ActiveRecord 
     | 
|
| 
       209 
208 
     | 
    
         
             
                end
         
     | 
| 
       210 
209 
     | 
    
         | 
| 
       211 
210 
     | 
    
         
             
                private
         
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
       213 
211 
     | 
    
         
             
                  def has_include?(column_name)
         
     | 
| 
       214 
212 
     | 
    
         
             
                    eager_loading? || (includes_values.present? && column_name && column_name != :all)
         
     | 
| 
       215 
213 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -224,10 +222,12 @@ module ActiveRecord 
     | 
|
| 
       224 
222 
     | 
    
         
             
                    if operation == "count"
         
     | 
| 
       225 
223 
     | 
    
         
             
                      column_name ||= select_for_count
         
     | 
| 
       226 
224 
     | 
    
         
             
                      if column_name == :all
         
     | 
| 
       227 
     | 
    
         
            -
                        if distinct 
     | 
| 
      
 225 
     | 
    
         
            +
                        if !distinct
         
     | 
| 
      
 226 
     | 
    
         
            +
                          distinct = distinct_select?(select_for_count) if group_values.empty?
         
     | 
| 
      
 227 
     | 
    
         
            +
                        elsif group_values.any? || select_values.empty? && order_values.empty?
         
     | 
| 
       228 
228 
     | 
    
         
             
                          column_name = primary_key
         
     | 
| 
       229 
229 
     | 
    
         
             
                        end
         
     | 
| 
       230 
     | 
    
         
            -
                      elsif column_name 
     | 
| 
      
 230 
     | 
    
         
            +
                      elsif distinct_select?(column_name)
         
     | 
| 
       231 
231 
     | 
    
         
             
                        distinct = nil
         
     | 
| 
       232 
232 
     | 
    
         
             
                      end
         
     | 
| 
       233 
233 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -239,6 +239,10 @@ module ActiveRecord 
     | 
|
| 
       239 
239 
     | 
    
         
             
                    end
         
     | 
| 
       240 
240 
     | 
    
         
             
                  end
         
     | 
| 
       241 
241 
     | 
    
         | 
| 
      
 242 
     | 
    
         
            +
                  def distinct_select?(column_name)
         
     | 
| 
      
 243 
     | 
    
         
            +
                    column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name)
         
     | 
| 
      
 244 
     | 
    
         
            +
                  end
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
       242 
246 
     | 
    
         
             
                  def aggregate_column(column_name)
         
     | 
| 
       243 
247 
     | 
    
         
             
                    return column_name if Arel::Expressions === column_name
         
     | 
| 
       244 
248 
     | 
    
         | 
| 
         @@ -383,7 +387,7 @@ module ActiveRecord 
     | 
|
| 
       383 
387 
     | 
    
         
             
                    case operation
         
     | 
| 
       384 
388 
     | 
    
         
             
                    when "count"   then value.to_i
         
     | 
| 
       385 
389 
     | 
    
         
             
                    when "sum"     then type.deserialize(value || 0)
         
     | 
| 
       386 
     | 
    
         
            -
                    when "average" then value.respond_to?(:to_d) ? value.to_d : value
         
     | 
| 
      
 390 
     | 
    
         
            +
                    when "average" then value && value.respond_to?(:to_d) ? value.to_d : value
         
     | 
| 
       387 
391 
     | 
    
         
             
                    else type.deserialize(value)
         
     | 
| 
       388 
392 
     | 
    
         
             
                    end
         
     | 
| 
       389 
393 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -17,6 +17,7 @@ module ActiveRecord 
     | 
|
| 
       17 
17 
     | 
    
         
             
                      delegate = Class.new(klass) {
         
     | 
| 
       18 
18 
     | 
    
         
             
                        include ClassSpecificRelation
         
     | 
| 
       19 
19 
     | 
    
         
             
                      }
         
     | 
| 
      
 20 
     | 
    
         
            +
                      include_relation_methods(delegate)
         
     | 
| 
       20 
21 
     | 
    
         
             
                      mangled_name = klass.name.gsub("::".freeze, "_".freeze)
         
     | 
| 
       21 
22 
     | 
    
         
             
                      const_set mangled_name, delegate
         
     | 
| 
       22 
23 
     | 
    
         
             
                      private_constant mangled_name
         
     | 
| 
         @@ -29,6 +30,35 @@ module ActiveRecord 
     | 
|
| 
       29 
30 
     | 
    
         
             
                    child_class.initialize_relation_delegate_cache
         
     | 
| 
       30 
31 
     | 
    
         
             
                    super
         
     | 
| 
       31 
32 
     | 
    
         
             
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 35 
     | 
    
         
            +
                    def include_relation_methods(delegate)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      superclass.include_relation_methods(delegate) unless base_class == self
         
     | 
| 
      
 37 
     | 
    
         
            +
                      delegate.include generated_relation_methods
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  private
         
     | 
| 
      
 41 
     | 
    
         
            +
                    def generated_relation_methods
         
     | 
| 
      
 42 
     | 
    
         
            +
                      @generated_relation_methods ||= Module.new.tap do |mod|
         
     | 
| 
      
 43 
     | 
    
         
            +
                        mod_name = "GeneratedRelationMethods"
         
     | 
| 
      
 44 
     | 
    
         
            +
                        const_set mod_name, mod
         
     | 
| 
      
 45 
     | 
    
         
            +
                        private_constant mod_name
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    def generate_relation_method(method)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method)
         
     | 
| 
      
 51 
     | 
    
         
            +
                        generated_relation_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
      
 52 
     | 
    
         
            +
                          def #{method}(*args, &block)
         
     | 
| 
      
 53 
     | 
    
         
            +
                            scoping { klass.#{method}(*args, &block) }
         
     | 
| 
      
 54 
     | 
    
         
            +
                          end
         
     | 
| 
      
 55 
     | 
    
         
            +
                        RUBY
         
     | 
| 
      
 56 
     | 
    
         
            +
                      else
         
     | 
| 
      
 57 
     | 
    
         
            +
                        generated_relation_methods.send(:define_method, method) do |*args, &block|
         
     | 
| 
      
 58 
     | 
    
         
            +
                          scoping { klass.public_send(method, *args, &block) }
         
     | 
| 
      
 59 
     | 
    
         
            +
                        end
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end
         
     | 
| 
       32 
62 
     | 
    
         
             
                end
         
     | 
| 
       33 
63 
     | 
    
         | 
| 
       34 
64 
     | 
    
         
             
                extend ActiveSupport::Concern
         
     | 
| 
         @@ -319,7 +319,7 @@ module ActiveRecord 
     | 
|
| 
       319 
319 
     | 
    
         | 
| 
       320 
320 
     | 
    
         
             
                  relation = construct_relation_for_exists(conditions)
         
     | 
| 
       321 
321 
     | 
    
         | 
| 
       322 
     | 
    
         
            -
                  skip_query_cache_if_necessary { connection. 
     | 
| 
      
 322 
     | 
    
         
            +
                  skip_query_cache_if_necessary { connection.select_one(relation.arel, "#{name} Exists") } ? true : false
         
     | 
| 
       323 
323 
     | 
    
         
             
                rescue ::RangeError
         
     | 
| 
       324 
324 
     | 
    
         
             
                  false
         
     | 
| 
       325 
325 
     | 
    
         
             
                end
         
     | 
| 
         @@ -359,11 +359,15 @@ module ActiveRecord 
     | 
|
| 
       359 
359 
     | 
    
         
             
                  end
         
     | 
| 
       360 
360 
     | 
    
         | 
| 
       361 
361 
     | 
    
         
             
                  def construct_relation_for_exists(conditions)
         
     | 
| 
       362 
     | 
    
         
            -
                     
     | 
| 
      
 362 
     | 
    
         
            +
                    if distinct_value && offset_value
         
     | 
| 
      
 363 
     | 
    
         
            +
                      relation = except(:order).limit!(1)
         
     | 
| 
      
 364 
     | 
    
         
            +
                    else
         
     | 
| 
      
 365 
     | 
    
         
            +
                      relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
         
     | 
| 
      
 366 
     | 
    
         
            +
                    end
         
     | 
| 
       363 
367 
     | 
    
         | 
| 
       364 
368 
     | 
    
         
             
                    case conditions
         
     | 
| 
       365 
369 
     | 
    
         
             
                    when Array, Hash
         
     | 
| 
       366 
     | 
    
         
            -
                      relation.where!(conditions)
         
     | 
| 
      
 370 
     | 
    
         
            +
                      relation.where!(conditions) unless conditions.empty?
         
     | 
| 
       367 
371 
     | 
    
         
             
                    else
         
     | 
| 
       368 
372 
     | 
    
         
             
                      relation.where!(primary_key => conditions) unless conditions == :none
         
     | 
| 
       369 
373 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -417,7 +421,7 @@ module ActiveRecord 
     | 
|
| 
       417 
421 
     | 
    
         
             
                    raise UnknownPrimaryKey.new(@klass) if primary_key.nil?
         
     | 
| 
       418 
422 
     | 
    
         | 
| 
       419 
423 
     | 
    
         
             
                    expects_array = ids.first.kind_of?(Array)
         
     | 
| 
       420 
     | 
    
         
            -
                    return  
     | 
| 
      
 424 
     | 
    
         
            +
                    return [] if expects_array && ids.first.empty?
         
     | 
| 
       421 
425 
     | 
    
         | 
| 
       422 
426 
     | 
    
         
             
                    ids = ids.flatten.compact.uniq
         
     | 
| 
       423 
427 
     | 
    
         | 
| 
         @@ -156,10 +156,10 @@ module ActiveRecord 
     | 
|
| 
       156 
156 
     | 
    
         
             
                    def merge_multi_values
         
     | 
| 
       157 
157 
     | 
    
         
             
                      if other.reordering_value
         
     | 
| 
       158 
158 
     | 
    
         
             
                        # override any order specified in the original relation
         
     | 
| 
       159 
     | 
    
         
            -
                        relation.reorder! 
     | 
| 
      
 159 
     | 
    
         
            +
                        relation.reorder!(*other.order_values)
         
     | 
| 
       160 
160 
     | 
    
         
             
                      elsif other.order_values.any?
         
     | 
| 
       161 
161 
     | 
    
         
             
                        # merge in order_values from relation
         
     | 
| 
       162 
     | 
    
         
            -
                        relation.order! 
     | 
| 
      
 162 
     | 
    
         
            +
                        relation.order!(*other.order_values)
         
     | 
| 
       163 
163 
     | 
    
         
             
                      end
         
     | 
| 
       164 
164 
     | 
    
         | 
| 
       165 
165 
     | 
    
         
             
                      extensions = other.extensions - relation.extensions
         
     | 
| 
         @@ -175,9 +175,7 @@ module ActiveRecord 
     | 
|
| 
       175 
175 
     | 
    
         
             
                    end
         
     | 
| 
       176 
176 
     | 
    
         | 
| 
       177 
177 
     | 
    
         
             
                    def merge_clauses
         
     | 
| 
       178 
     | 
    
         
            -
                       
     | 
| 
       179 
     | 
    
         
            -
                        relation.from_clause = other.from_clause
         
     | 
| 
       180 
     | 
    
         
            -
                      end
         
     | 
| 
      
 178 
     | 
    
         
            +
                      relation.from_clause = other.from_clause if replace_from_clause?
         
     | 
| 
       181 
179 
     | 
    
         | 
| 
       182 
180 
     | 
    
         
             
                      where_clause = relation.where_clause.merge(other.where_clause)
         
     | 
| 
       183 
181 
     | 
    
         
             
                      relation.where_clause = where_clause unless where_clause.empty?
         
     | 
| 
         @@ -185,6 +183,11 @@ module ActiveRecord 
     | 
|
| 
       185 
183 
     | 
    
         
             
                      having_clause = relation.having_clause.merge(other.having_clause)
         
     | 
| 
       186 
184 
     | 
    
         
             
                      relation.having_clause = having_clause unless having_clause.empty?
         
     | 
| 
       187 
185 
     | 
    
         
             
                    end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                    def replace_from_clause?
         
     | 
| 
      
 188 
     | 
    
         
            +
                      relation.from_clause.empty? && !other.from_clause.empty? &&
         
     | 
| 
      
 189 
     | 
    
         
            +
                        relation.klass.base_class == other.klass.base_class
         
     | 
| 
      
 190 
     | 
    
         
            +
                    end
         
     | 
| 
       188 
191 
     | 
    
         
             
                end
         
     | 
| 
       189 
192 
     | 
    
         
             
              end
         
     | 
| 
       190 
193 
     | 
    
         
             
            end
         
     | 
| 
         @@ -93,16 +93,21 @@ module ActiveRecord 
     | 
|
| 
       93 
93 
     | 
    
         
             
                        queries.reduce(&:or)
         
     | 
| 
       94 
94 
     | 
    
         
             
                      elsif table.aggregated_with?(key)
         
     | 
| 
       95 
95 
     | 
    
         
             
                        mapping = table.reflect_on_aggregation(key).mapping
         
     | 
| 
       96 
     | 
    
         
            -
                         
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
                             
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
      
 96 
     | 
    
         
            +
                        values = value.nil? ? [nil] : Array.wrap(value)
         
     | 
| 
      
 97 
     | 
    
         
            +
                        if mapping.length == 1 || values.empty?
         
     | 
| 
      
 98 
     | 
    
         
            +
                          column_name, aggr_attr = mapping.first
         
     | 
| 
      
 99 
     | 
    
         
            +
                          values = values.map do |object|
         
     | 
| 
      
 100 
     | 
    
         
            +
                            object.respond_to?(aggr_attr) ? object.public_send(aggr_attr) : object
         
     | 
| 
      
 101 
     | 
    
         
            +
                          end
         
     | 
| 
      
 102 
     | 
    
         
            +
                          build(table.arel_attribute(column_name), values)
         
     | 
| 
      
 103 
     | 
    
         
            +
                        else
         
     | 
| 
      
 104 
     | 
    
         
            +
                          queries = values.map do |object|
         
     | 
| 
      
 105 
     | 
    
         
            +
                            mapping.map do |field_attr, aggregate_attr|
         
     | 
| 
      
 106 
     | 
    
         
            +
                              build(table.arel_attribute(field_attr), object.try!(aggregate_attr))
         
     | 
| 
      
 107 
     | 
    
         
            +
                            end.reduce(&:and)
         
     | 
| 
      
 108 
     | 
    
         
            +
                          end
         
     | 
| 
      
 109 
     | 
    
         
            +
                          queries.reduce(&:or)
         
     | 
| 
       104 
110 
     | 
    
         
             
                        end
         
     | 
| 
       105 
     | 
    
         
            -
                        queries.reduce(&:or)
         
     | 
| 
       106 
111 
     | 
    
         
             
                      else
         
     | 
| 
       107 
112 
     | 
    
         
             
                        build(table.arel_attribute(key), value)
         
     | 
| 
       108 
113 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -19,10 +19,10 @@ module ActiveRecord 
     | 
|
| 
       19 
19 
     | 
    
         
             
                      when 0 then NullPredicate
         
     | 
| 
       20 
20 
     | 
    
         
             
                      when 1 then predicate_builder.build(attribute, values.first)
         
     | 
| 
       21 
21 
     | 
    
         
             
                      else
         
     | 
| 
       22 
     | 
    
         
            -
                         
     | 
| 
      
 22 
     | 
    
         
            +
                        values.map! do |v|
         
     | 
| 
       23 
23 
     | 
    
         
             
                          predicate_builder.build_bind_attribute(attribute.name, v)
         
     | 
| 
       24 
24 
     | 
    
         
             
                        end
         
     | 
| 
       25 
     | 
    
         
            -
                        attribute.in( 
     | 
| 
      
 25 
     | 
    
         
            +
                        values.empty? ? NullPredicate : attribute.in(values)
         
     | 
| 
       26 
26 
     | 
    
         
             
                      end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                    unless nils.empty?
         
     | 
| 
         @@ -18,13 +18,15 @@ module ActiveRecord 
     | 
|
| 
       18 
18 
     | 
    
         
             
                  end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                  def nil?
         
     | 
| 
       21 
     | 
    
         
            -
                     
     | 
| 
       22 
     | 
    
         
            -
                       
     | 
| 
      
 21 
     | 
    
         
            +
                    unless value_before_type_cast.is_a?(StatementCache::Substitute)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      value_before_type_cast.nil? ||
         
     | 
| 
      
 23 
     | 
    
         
            +
                        type.respond_to?(:subtype, true) && value_for_database.nil?
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
       23 
25 
     | 
    
         
             
                  end
         
     | 
| 
       24 
26 
     | 
    
         | 
| 
       25 
27 
     | 
    
         
             
                  def boundable?
         
     | 
| 
       26 
28 
     | 
    
         
             
                    return @_boundable if defined?(@_boundable)
         
     | 
| 
       27 
     | 
    
         
            -
                     
     | 
| 
      
 29 
     | 
    
         
            +
                    value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
         
     | 
| 
       28 
30 
     | 
    
         
             
                    @_boundable = true
         
     | 
| 
       29 
31 
     | 
    
         
             
                  rescue ::RangeError
         
     | 
| 
       30 
32 
     | 
    
         
             
                    @_boundable = false
         
     | 
| 
         @@ -232,9 +232,6 @@ module ActiveRecord 
     | 
|
| 
       232 
232 
     | 
    
         | 
| 
       233 
233 
     | 
    
         
             
                def _select!(*fields) # :nodoc:
         
     | 
| 
       234 
234 
     | 
    
         
             
                  fields.flatten!
         
     | 
| 
       235 
     | 
    
         
            -
                  fields.map! do |field|
         
     | 
| 
       236 
     | 
    
         
            -
                    klass.attribute_alias?(field) ? klass.attribute_alias(field).to_sym : field
         
     | 
| 
       237 
     | 
    
         
            -
                  end
         
     | 
| 
       238 
235 
     | 
    
         
             
                  self.select_values += fields
         
     | 
| 
       239 
236 
     | 
    
         
             
                  self
         
     | 
| 
       240 
237 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1051,11 +1048,14 @@ module ActiveRecord 
     | 
|
| 
       1051 
1048 
     | 
    
         | 
| 
       1052 
1049 
     | 
    
         
             
                  def arel_columns(columns)
         
     | 
| 
       1053 
1050 
     | 
    
         
             
                    columns.flat_map do |field|
         
     | 
| 
       1054 
     | 
    
         
            -
                       
     | 
| 
       1055 
     | 
    
         
            -
             
     | 
| 
       1056 
     | 
    
         
            -
             
     | 
| 
       1057 
     | 
    
         
            -
             
     | 
| 
       1058 
     | 
    
         
            -
             
     | 
| 
      
 1051 
     | 
    
         
            +
                      case field
         
     | 
| 
      
 1052 
     | 
    
         
            +
                      when Symbol
         
     | 
| 
      
 1053 
     | 
    
         
            +
                        arel_column(field.to_s) do |attr_name|
         
     | 
| 
      
 1054 
     | 
    
         
            +
                          connection.quote_table_name(attr_name)
         
     | 
| 
      
 1055 
     | 
    
         
            +
                        end
         
     | 
| 
      
 1056 
     | 
    
         
            +
                      when String
         
     | 
| 
      
 1057 
     | 
    
         
            +
                        arel_column(field, &:itself)
         
     | 
| 
      
 1058 
     | 
    
         
            +
                      when Proc
         
     | 
| 
       1059 
1059 
     | 
    
         
             
                        field.call
         
     | 
| 
       1060 
1060 
     | 
    
         
             
                      else
         
     | 
| 
       1061 
1061 
     | 
    
         
             
                        field
         
     | 
| 
         @@ -1063,6 +1063,21 @@ module ActiveRecord 
     | 
|
| 
       1063 
1063 
     | 
    
         
             
                    end
         
     | 
| 
       1064 
1064 
     | 
    
         
             
                  end
         
     | 
| 
       1065 
1065 
     | 
    
         | 
| 
      
 1066 
     | 
    
         
            +
                  def arel_column(field)
         
     | 
| 
      
 1067 
     | 
    
         
            +
                    field = klass.attribute_alias(field) if klass.attribute_alias?(field)
         
     | 
| 
      
 1068 
     | 
    
         
            +
                    from = from_clause.name || from_clause.value
         
     | 
| 
      
 1069 
     | 
    
         
            +
             
     | 
| 
      
 1070 
     | 
    
         
            +
                    if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
         
     | 
| 
      
 1071 
     | 
    
         
            +
                      arel_attribute(field)
         
     | 
| 
      
 1072 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1073 
     | 
    
         
            +
                      yield field
         
     | 
| 
      
 1074 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1075 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1076 
     | 
    
         
            +
             
     | 
| 
      
 1077 
     | 
    
         
            +
                  def table_name_matches?(from)
         
     | 
| 
      
 1078 
     | 
    
         
            +
                    /(?:\A|(?<!FROM)\s)(?:\b#{table.name}\b|#{connection.quote_table_name(table.name)})(?!\.)/i.match?(from.to_s)
         
     | 
| 
      
 1079 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1080 
     | 
    
         
            +
             
     | 
| 
       1066 
1081 
     | 
    
         
             
                  def reverse_sql_order(order_query)
         
     | 
| 
       1067 
1082 
     | 
    
         
             
                    if order_query.empty?
         
     | 
| 
       1068 
1083 
     | 
    
         
             
                      return [arel_attribute(primary_key).desc] if primary_key
         
     | 
| 
         @@ -1144,14 +1159,14 @@ module ActiveRecord 
     | 
|
| 
       1144 
1159 
     | 
    
         
             
                    order_args.map! do |arg|
         
     | 
| 
       1145 
1160 
     | 
    
         
             
                      case arg
         
     | 
| 
       1146 
1161 
     | 
    
         
             
                      when Symbol
         
     | 
| 
       1147 
     | 
    
         
            -
                         
     | 
| 
      
 1162 
     | 
    
         
            +
                        order_column(arg.to_s).asc
         
     | 
| 
       1148 
1163 
     | 
    
         
             
                      when Hash
         
     | 
| 
       1149 
1164 
     | 
    
         
             
                        arg.map { |field, dir|
         
     | 
| 
       1150 
1165 
     | 
    
         
             
                          case field
         
     | 
| 
       1151 
1166 
     | 
    
         
             
                          when Arel::Nodes::SqlLiteral
         
     | 
| 
       1152 
1167 
     | 
    
         
             
                            field.send(dir.downcase)
         
     | 
| 
       1153 
1168 
     | 
    
         
             
                          else
         
     | 
| 
       1154 
     | 
    
         
            -
                             
     | 
| 
      
 1169 
     | 
    
         
            +
                            order_column(field.to_s).send(dir.downcase)
         
     | 
| 
       1155 
1170 
     | 
    
         
             
                          end
         
     | 
| 
       1156 
1171 
     | 
    
         
             
                        }
         
     | 
| 
       1157 
1172 
     | 
    
         
             
                      else
         
     | 
| 
         @@ -1160,6 +1175,16 @@ module ActiveRecord 
     | 
|
| 
       1160 
1175 
     | 
    
         
             
                    end.flatten!
         
     | 
| 
       1161 
1176 
     | 
    
         
             
                  end
         
     | 
| 
       1162 
1177 
     | 
    
         | 
| 
      
 1178 
     | 
    
         
            +
                  def order_column(field)
         
     | 
| 
      
 1179 
     | 
    
         
            +
                    arel_column(field) do |attr_name|
         
     | 
| 
      
 1180 
     | 
    
         
            +
                      if attr_name == "count" && !group_values.empty?
         
     | 
| 
      
 1181 
     | 
    
         
            +
                        arel_attribute(attr_name)
         
     | 
| 
      
 1182 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1183 
     | 
    
         
            +
                        Arel.sql(connection.quote_table_name(attr_name))
         
     | 
| 
      
 1184 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1185 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1186 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1187 
     | 
    
         
            +
             
     | 
| 
       1163 
1188 
     | 
    
         
             
                  # Checks to make sure that the arguments are not blank. Note that if some
         
     | 
| 
       1164 
1189 
     | 
    
         
             
                  # blank-like object were initially passed into the query method, then this
         
     | 
| 
       1165 
1190 
     | 
    
         
             
                  # method will not raise an error.
         
     |