activerecord 5.1.5 → 5.2.1
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 +450 -699
 - data/MIT-LICENSE +1 -1
 - data/README.rdoc +5 -5
 - data/examples/performance.rb +2 -0
 - data/examples/simple.rb +2 -0
 - data/lib/active_record/aggregations.rb +6 -5
 - data/lib/active_record/association_relation.rb +4 -2
 - data/lib/active_record/associations/alias_tracker.rb +19 -27
 - data/lib/active_record/associations/association.rb +33 -37
 - data/lib/active_record/associations/association_scope.rb +38 -50
 - data/lib/active_record/associations/belongs_to_association.rb +28 -9
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
 - data/lib/active_record/associations/builder/association.rb +4 -7
 - data/lib/active_record/associations/builder/belongs_to.rb +14 -5
 - data/lib/active_record/associations/builder/collection_association.rb +1 -1
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
 - data/lib/active_record/associations/builder/has_many.rb +2 -0
 - data/lib/active_record/associations/builder/has_one.rb +2 -0
 - data/lib/active_record/associations/builder/singular_association.rb +2 -0
 - data/lib/active_record/associations/collection_association.rb +52 -41
 - data/lib/active_record/associations/collection_proxy.rb +12 -15
 - data/lib/active_record/associations/foreign_association.rb +2 -0
 - data/lib/active_record/associations/has_many_association.rb +3 -1
 - data/lib/active_record/associations/has_many_through_association.rb +8 -19
 - data/lib/active_record/associations/has_one_association.rb +12 -1
 - data/lib/active_record/associations/has_one_through_association.rb +13 -8
 - data/lib/active_record/associations/join_dependency/join_association.rb +22 -67
 - data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
 - data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
 - data/lib/active_record/associations/join_dependency.rb +48 -93
 - data/lib/active_record/associations/preloader/association.rb +45 -61
 - data/lib/active_record/associations/preloader/through_association.rb +71 -79
 - data/lib/active_record/associations/preloader.rb +17 -37
 - data/lib/active_record/associations/singular_association.rb +14 -16
 - data/lib/active_record/associations/through_association.rb +26 -11
 - data/lib/active_record/associations.rb +40 -63
 - data/lib/active_record/attribute_assignment.rb +2 -5
 - data/lib/active_record/attribute_decorators.rb +3 -2
 - data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
 - data/lib/active_record/attribute_methods/dirty.rb +25 -214
 - data/lib/active_record/attribute_methods/primary_key.rb +7 -6
 - data/lib/active_record/attribute_methods/query.rb +2 -0
 - data/lib/active_record/attribute_methods/read.rb +9 -3
 - data/lib/active_record/attribute_methods/serialization.rb +23 -0
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
 - data/lib/active_record/attribute_methods/write.rb +21 -9
 - data/lib/active_record/attribute_methods.rb +65 -24
 - data/lib/active_record/attributes.rb +7 -6
 - data/lib/active_record/autosave_association.rb +16 -14
 - data/lib/active_record/base.rb +2 -0
 - data/lib/active_record/callbacks.rb +12 -6
 - data/lib/active_record/coders/json.rb +2 -0
 - data/lib/active_record/coders/yaml_column.rb +2 -0
 - data/lib/active_record/collection_cache_key.rb +11 -7
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +157 -29
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -32
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +64 -6
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +149 -78
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +81 -96
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
 - data/lib/active_record/connection_adapters/column.rb +3 -1
 - data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
 - data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -2
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
 - data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
 - data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
 - data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +6 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
 - data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +248 -112
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -73
 - data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
 - data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +20 -1
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
 - data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
 - data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
 - data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +79 -92
 - data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
 - data/lib/active_record/connection_handling.rb +4 -2
 - data/lib/active_record/core.rb +39 -60
 - data/lib/active_record/counter_cache.rb +20 -15
 - data/lib/active_record/define_callbacks.rb +5 -3
 - data/lib/active_record/dynamic_matchers.rb +9 -9
 - data/lib/active_record/enum.rb +17 -13
 - data/lib/active_record/errors.rb +42 -3
 - data/lib/active_record/explain.rb +3 -1
 - data/lib/active_record/explain_registry.rb +2 -0
 - data/lib/active_record/explain_subscriber.rb +2 -0
 - data/lib/active_record/fixture_set/file.rb +2 -0
 - data/lib/active_record/fixtures.rb +67 -60
 - data/lib/active_record/gem_version.rb +4 -2
 - data/lib/active_record/inheritance.rb +49 -19
 - data/lib/active_record/integration.rb +58 -19
 - data/lib/active_record/internal_metadata.rb +2 -0
 - data/lib/active_record/legacy_yaml_adapter.rb +3 -1
 - data/lib/active_record/locking/optimistic.rb +30 -42
 - data/lib/active_record/locking/pessimistic.rb +9 -6
 - data/lib/active_record/log_subscriber.rb +43 -0
 - data/lib/active_record/migration/command_recorder.rb +11 -9
 - data/lib/active_record/migration/compatibility.rb +40 -2
 - data/lib/active_record/migration/join_table.rb +2 -0
 - data/lib/active_record/migration.rb +189 -139
 - data/lib/active_record/model_schema.rb +19 -24
 - data/lib/active_record/nested_attributes.rb +18 -6
 - data/lib/active_record/no_touching.rb +3 -1
 - data/lib/active_record/null_relation.rb +2 -0
 - data/lib/active_record/persistence.rb +196 -48
 - data/lib/active_record/query_cache.rb +12 -14
 - data/lib/active_record/querying.rb +3 -1
 - data/lib/active_record/railtie.rb +61 -3
 - data/lib/active_record/railties/console_sandbox.rb +2 -0
 - data/lib/active_record/railties/controller_runtime.rb +2 -0
 - data/lib/active_record/railties/databases.rake +46 -36
 - data/lib/active_record/readonly_attributes.rb +3 -2
 - data/lib/active_record/reflection.rb +110 -192
 - data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
 - data/lib/active_record/relation/batches.rb +20 -5
 - data/lib/active_record/relation/calculations.rb +31 -9
 - data/lib/active_record/relation/delegation.rb +15 -27
 - data/lib/active_record/relation/finder_methods.rb +71 -76
 - data/lib/active_record/relation/from_clause.rb +2 -8
 - data/lib/active_record/relation/merger.rb +47 -20
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
 - data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
 - data/lib/active_record/relation/predicate_builder.rb +55 -79
 - data/lib/active_record/relation/query_attribute.rb +26 -2
 - data/lib/active_record/relation/query_methods.rb +95 -91
 - data/lib/active_record/relation/record_fetch_warning.rb +2 -0
 - data/lib/active_record/relation/spawn_methods.rb +3 -1
 - data/lib/active_record/relation/where_clause.rb +65 -68
 - data/lib/active_record/relation/where_clause_factory.rb +5 -48
 - data/lib/active_record/relation.rb +106 -219
 - data/lib/active_record/result.rb +2 -0
 - data/lib/active_record/runtime_registry.rb +2 -0
 - data/lib/active_record/sanitization.rb +129 -121
 - data/lib/active_record/schema.rb +4 -2
 - data/lib/active_record/schema_dumper.rb +36 -26
 - data/lib/active_record/schema_migration.rb +2 -0
 - data/lib/active_record/scoping/default.rb +6 -7
 - data/lib/active_record/scoping/named.rb +21 -7
 - data/lib/active_record/scoping.rb +9 -8
 - data/lib/active_record/secure_token.rb +2 -0
 - data/lib/active_record/serialization.rb +2 -0
 - data/lib/active_record/statement_cache.rb +22 -12
 - data/lib/active_record/store.rb +3 -1
 - data/lib/active_record/suppressor.rb +2 -0
 - data/lib/active_record/table_metadata.rb +12 -3
 - data/lib/active_record/tasks/database_tasks.rb +25 -14
 - data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
 - data/lib/active_record/timestamp.rb +13 -6
 - data/lib/active_record/touch_later.rb +2 -0
 - data/lib/active_record/transactions.rb +32 -27
 - data/lib/active_record/translation.rb +2 -0
 - data/lib/active_record/type/adapter_specific_registry.rb +2 -0
 - data/lib/active_record/type/date.rb +2 -0
 - data/lib/active_record/type/date_time.rb +2 -0
 - data/lib/active_record/type/decimal_without_scale.rb +2 -0
 - data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
 - data/lib/active_record/type/internal/timezone.rb +2 -0
 - data/lib/active_record/type/json.rb +30 -0
 - data/lib/active_record/type/serialized.rb +6 -0
 - data/lib/active_record/type/text.rb +2 -0
 - data/lib/active_record/type/time.rb +2 -0
 - data/lib/active_record/type/type_map.rb +2 -0
 - data/lib/active_record/type/unsigned_integer.rb +2 -0
 - data/lib/active_record/type.rb +4 -1
 - data/lib/active_record/type_caster/connection.rb +2 -0
 - data/lib/active_record/type_caster/map.rb +3 -1
 - data/lib/active_record/type_caster.rb +2 -0
 - data/lib/active_record/validations/absence.rb +2 -0
 - data/lib/active_record/validations/associated.rb +2 -0
 - data/lib/active_record/validations/length.rb +2 -0
 - data/lib/active_record/validations/presence.rb +2 -0
 - data/lib/active_record/validations/uniqueness.rb +36 -6
 - data/lib/active_record/validations.rb +2 -0
 - data/lib/active_record/version.rb +2 -0
 - data/lib/active_record.rb +11 -4
 - data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
 - data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
 - data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
 - data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
 - data/lib/rails/generators/active_record/migration.rb +2 -0
 - data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
 - data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
 - data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
 - data/lib/rails/generators/active_record.rb +3 -1
 - metadata +23 -36
 - data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
 - data/lib/active_record/associations/preloader/collection_association.rb +0 -17
 - data/lib/active_record/associations/preloader/has_many.rb +0 -15
 - data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
 - data/lib/active_record/associations/preloader/has_one.rb +0 -15
 - data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
 - data/lib/active_record/associations/preloader/singular_association.rb +0 -18
 - data/lib/active_record/attribute/user_provided_default.rb +0 -30
 - data/lib/active_record/attribute.rb +0 -240
 - data/lib/active_record/attribute_mutation_tracker.rb +0 -114
 - data/lib/active_record/attribute_set/builder.rb +0 -124
 - data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
 - data/lib/active_record/attribute_set.rb +0 -113
 - data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
 - data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
 - data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
 - data/lib/active_record/type/internal/abstract_json.rb +0 -37
 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       2 
4 
     | 
    
         
             
              # = Active Record \Persistence
         
     | 
| 
       3 
5 
     | 
    
         
             
              module Persistence
         
     | 
| 
         @@ -69,6 +71,142 @@ module ActiveRecord 
     | 
|
| 
       69 
71 
     | 
    
         
             
                    klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block)
         
     | 
| 
       70 
72 
     | 
    
         
             
                  end
         
     | 
| 
       71 
73 
     | 
    
         | 
| 
      
 74 
     | 
    
         
            +
                  # Updates an object (or multiple objects) and saves it to the database, if validations pass.
         
     | 
| 
      
 75 
     | 
    
         
            +
                  # The resulting object is returned whether the object was saved successfully to the database or not.
         
     | 
| 
      
 76 
     | 
    
         
            +
                  #
         
     | 
| 
      
 77 
     | 
    
         
            +
                  # ==== Parameters
         
     | 
| 
      
 78 
     | 
    
         
            +
                  #
         
     | 
| 
      
 79 
     | 
    
         
            +
                  # * +id+ - This should be the id or an array of ids to be updated.
         
     | 
| 
      
 80 
     | 
    
         
            +
                  # * +attributes+ - This should be a hash of attributes or an array of hashes.
         
     | 
| 
      
 81 
     | 
    
         
            +
                  #
         
     | 
| 
      
 82 
     | 
    
         
            +
                  # ==== Examples
         
     | 
| 
      
 83 
     | 
    
         
            +
                  #
         
     | 
| 
      
 84 
     | 
    
         
            +
                  #   # Updates one record
         
     | 
| 
      
 85 
     | 
    
         
            +
                  #   Person.update(15, user_name: "Samuel", group: "expert")
         
     | 
| 
      
 86 
     | 
    
         
            +
                  #
         
     | 
| 
      
 87 
     | 
    
         
            +
                  #   # Updates multiple records
         
     | 
| 
      
 88 
     | 
    
         
            +
                  #   people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
         
     | 
| 
      
 89 
     | 
    
         
            +
                  #   Person.update(people.keys, people.values)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  #
         
     | 
| 
      
 91 
     | 
    
         
            +
                  #   # Updates multiple records from the result of a relation
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #   people = Person.where(group: "expert")
         
     | 
| 
      
 93 
     | 
    
         
            +
                  #   people.update(group: "masters")
         
     | 
| 
      
 94 
     | 
    
         
            +
                  #
         
     | 
| 
      
 95 
     | 
    
         
            +
                  # Note: Updating a large number of records will run an UPDATE
         
     | 
| 
      
 96 
     | 
    
         
            +
                  # query for each record, which may cause a performance issue.
         
     | 
| 
      
 97 
     | 
    
         
            +
                  # When running callbacks is not needed for each record update,
         
     | 
| 
      
 98 
     | 
    
         
            +
                  # it is preferred to use {update_all}[rdoc-ref:Relation#update_all]
         
     | 
| 
      
 99 
     | 
    
         
            +
                  # for updating all records in a single query.
         
     | 
| 
      
 100 
     | 
    
         
            +
                  def update(id = :all, attributes)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    if id.is_a?(Array)
         
     | 
| 
      
 102 
     | 
    
         
            +
                      id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
         
     | 
| 
      
 103 
     | 
    
         
            +
                        object.update(attributes[idx])
         
     | 
| 
      
 104 
     | 
    
         
            +
                      }
         
     | 
| 
      
 105 
     | 
    
         
            +
                    elsif id == :all
         
     | 
| 
      
 106 
     | 
    
         
            +
                      all.each { |record| record.update(attributes) }
         
     | 
| 
      
 107 
     | 
    
         
            +
                    else
         
     | 
| 
      
 108 
     | 
    
         
            +
                      if ActiveRecord::Base === id
         
     | 
| 
      
 109 
     | 
    
         
            +
                        raise ArgumentError,
         
     | 
| 
      
 110 
     | 
    
         
            +
                          "You are passing an instance of ActiveRecord::Base to `update`. " \
         
     | 
| 
      
 111 
     | 
    
         
            +
                          "Please pass the id of the object by calling `.id`."
         
     | 
| 
      
 112 
     | 
    
         
            +
                      end
         
     | 
| 
      
 113 
     | 
    
         
            +
                      object = find(id)
         
     | 
| 
      
 114 
     | 
    
         
            +
                      object.update(attributes)
         
     | 
| 
      
 115 
     | 
    
         
            +
                      object
         
     | 
| 
      
 116 
     | 
    
         
            +
                    end
         
     | 
| 
      
 117 
     | 
    
         
            +
                  end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                  # Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
         
     | 
| 
      
 120 
     | 
    
         
            +
                  # therefore all callbacks and filters are fired off before the object is deleted. This method is
         
     | 
| 
      
 121 
     | 
    
         
            +
                  # less efficient than #delete but allows cleanup methods and other actions to be run.
         
     | 
| 
      
 122 
     | 
    
         
            +
                  #
         
     | 
| 
      
 123 
     | 
    
         
            +
                  # This essentially finds the object (or multiple objects) with the given id, creates a new object
         
     | 
| 
      
 124 
     | 
    
         
            +
                  # from the attributes, and then calls destroy on it.
         
     | 
| 
      
 125 
     | 
    
         
            +
                  #
         
     | 
| 
      
 126 
     | 
    
         
            +
                  # ==== Parameters
         
     | 
| 
      
 127 
     | 
    
         
            +
                  #
         
     | 
| 
      
 128 
     | 
    
         
            +
                  # * +id+ - This should be the id or an array of ids to be destroyed.
         
     | 
| 
      
 129 
     | 
    
         
            +
                  #
         
     | 
| 
      
 130 
     | 
    
         
            +
                  # ==== Examples
         
     | 
| 
      
 131 
     | 
    
         
            +
                  #
         
     | 
| 
      
 132 
     | 
    
         
            +
                  #   # Destroy a single object
         
     | 
| 
      
 133 
     | 
    
         
            +
                  #   Todo.destroy(1)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  #
         
     | 
| 
      
 135 
     | 
    
         
            +
                  #   # Destroy multiple objects
         
     | 
| 
      
 136 
     | 
    
         
            +
                  #   todos = [1,2,3]
         
     | 
| 
      
 137 
     | 
    
         
            +
                  #   Todo.destroy(todos)
         
     | 
| 
      
 138 
     | 
    
         
            +
                  def destroy(id)
         
     | 
| 
      
 139 
     | 
    
         
            +
                    if id.is_a?(Array)
         
     | 
| 
      
 140 
     | 
    
         
            +
                      find(id).each(&:destroy)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    else
         
     | 
| 
      
 142 
     | 
    
         
            +
                      find(id).destroy
         
     | 
| 
      
 143 
     | 
    
         
            +
                    end
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                  # Deletes the row with a primary key matching the +id+ argument, using a
         
     | 
| 
      
 147 
     | 
    
         
            +
                  # SQL +DELETE+ statement, and returns the number of rows deleted. Active
         
     | 
| 
      
 148 
     | 
    
         
            +
                  # Record objects are not instantiated, so the object's callbacks are not
         
     | 
| 
      
 149 
     | 
    
         
            +
                  # executed, including any <tt>:dependent</tt> association options.
         
     | 
| 
      
 150 
     | 
    
         
            +
                  #
         
     | 
| 
      
 151 
     | 
    
         
            +
                  # You can delete multiple rows at once by passing an Array of <tt>id</tt>s.
         
     | 
| 
      
 152 
     | 
    
         
            +
                  #
         
     | 
| 
      
 153 
     | 
    
         
            +
                  # Note: Although it is often much faster than the alternative, #destroy,
         
     | 
| 
      
 154 
     | 
    
         
            +
                  # skipping callbacks might bypass business logic in your application
         
     | 
| 
      
 155 
     | 
    
         
            +
                  # that ensures referential integrity or performs other essential jobs.
         
     | 
| 
      
 156 
     | 
    
         
            +
                  #
         
     | 
| 
      
 157 
     | 
    
         
            +
                  # ==== Examples
         
     | 
| 
      
 158 
     | 
    
         
            +
                  #
         
     | 
| 
      
 159 
     | 
    
         
            +
                  #   # Delete a single row
         
     | 
| 
      
 160 
     | 
    
         
            +
                  #   Todo.delete(1)
         
     | 
| 
      
 161 
     | 
    
         
            +
                  #
         
     | 
| 
      
 162 
     | 
    
         
            +
                  #   # Delete multiple rows
         
     | 
| 
      
 163 
     | 
    
         
            +
                  #   Todo.delete([2,3,4])
         
     | 
| 
      
 164 
     | 
    
         
            +
                  def delete(id_or_array)
         
     | 
| 
      
 165 
     | 
    
         
            +
                    where(primary_key => id_or_array).delete_all
         
     | 
| 
      
 166 
     | 
    
         
            +
                  end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                  def _insert_record(values) # :nodoc:
         
     | 
| 
      
 169 
     | 
    
         
            +
                    primary_key_value = nil
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
                    if primary_key && Hash === values
         
     | 
| 
      
 172 
     | 
    
         
            +
                      primary_key_value = values[primary_key]
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                      if !primary_key_value && prefetch_primary_key?
         
     | 
| 
      
 175 
     | 
    
         
            +
                        primary_key_value = next_sequence_value
         
     | 
| 
      
 176 
     | 
    
         
            +
                        values[primary_key] = primary_key_value
         
     | 
| 
      
 177 
     | 
    
         
            +
                      end
         
     | 
| 
      
 178 
     | 
    
         
            +
                    end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                    if values.empty?
         
     | 
| 
      
 181 
     | 
    
         
            +
                      im = arel_table.compile_insert(connection.empty_insert_statement_value)
         
     | 
| 
      
 182 
     | 
    
         
            +
                      im.into arel_table
         
     | 
| 
      
 183 
     | 
    
         
            +
                    else
         
     | 
| 
      
 184 
     | 
    
         
            +
                      im = arel_table.compile_insert(_substitute_values(values))
         
     | 
| 
      
 185 
     | 
    
         
            +
                    end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                    connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  end
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                  def _update_record(values, constraints) # :nodoc:
         
     | 
| 
      
 191 
     | 
    
         
            +
                    constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) }
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                    um = arel_table.where(
         
     | 
| 
      
 194 
     | 
    
         
            +
                      constraints.reduce(&:and)
         
     | 
| 
      
 195 
     | 
    
         
            +
                    ).compile_update(_substitute_values(values), primary_key)
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                    connection.update(um, "#{self} Update")
         
     | 
| 
      
 198 
     | 
    
         
            +
                  end
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                  def _delete_record(constraints) # :nodoc:
         
     | 
| 
      
 201 
     | 
    
         
            +
                    constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) }
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                    dm = Arel::DeleteManager.new
         
     | 
| 
      
 204 
     | 
    
         
            +
                    dm.from(arel_table)
         
     | 
| 
      
 205 
     | 
    
         
            +
                    dm.wheres = constraints
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                    connection.delete(dm, "#{self} Destroy")
         
     | 
| 
      
 208 
     | 
    
         
            +
                  end
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
       72 
210 
     | 
    
         
             
                  private
         
     | 
| 
       73 
211 
     | 
    
         
             
                    # Called by +instantiate+ to decide which class to use for a new
         
     | 
| 
       74 
212 
     | 
    
         
             
                    # record instance.
         
     | 
| 
         @@ -78,6 +216,14 @@ module ActiveRecord 
     | 
|
| 
       78 
216 
     | 
    
         
             
                    def discriminate_class_for_record(record)
         
     | 
| 
       79 
217 
     | 
    
         
             
                      self
         
     | 
| 
       80 
218 
     | 
    
         
             
                    end
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
                    def _substitute_values(values)
         
     | 
| 
      
 221 
     | 
    
         
            +
                      values.map do |name, value|
         
     | 
| 
      
 222 
     | 
    
         
            +
                        attr = arel_attribute(name)
         
     | 
| 
      
 223 
     | 
    
         
            +
                        bind = predicate_builder.build_bind_attribute(name, value)
         
     | 
| 
      
 224 
     | 
    
         
            +
                        [attr, bind]
         
     | 
| 
      
 225 
     | 
    
         
            +
                      end
         
     | 
| 
      
 226 
     | 
    
         
            +
                    end
         
     | 
| 
       81 
227 
     | 
    
         
             
                end
         
     | 
| 
       82 
228 
     | 
    
         | 
| 
       83 
229 
     | 
    
         
             
                # Returns true if this object hasn't been saved yet -- that is, a record
         
     | 
| 
         @@ -175,7 +321,7 @@ module ActiveRecord 
     | 
|
| 
       175 
321 
     | 
    
         
             
                # callbacks or any <tt>:dependent</tt> association
         
     | 
| 
       176 
322 
     | 
    
         
             
                # options, use <tt>#destroy</tt>.
         
     | 
| 
       177 
323 
     | 
    
         
             
                def delete
         
     | 
| 
       178 
     | 
    
         
            -
                   
     | 
| 
      
 324 
     | 
    
         
            +
                  _delete_row if persisted?
         
     | 
| 
       179 
325 
     | 
    
         
             
                  @destroyed = true
         
     | 
| 
       180 
326 
     | 
    
         
             
                  freeze
         
     | 
| 
       181 
327 
     | 
    
         
             
                end
         
     | 
| 
         @@ -224,9 +370,10 @@ module ActiveRecord 
     | 
|
| 
       224 
370 
     | 
    
         
             
                # Any change to the attributes on either instance will affect both instances.
         
     | 
| 
       225 
371 
     | 
    
         
             
                # If you want to change the sti column as well, use #becomes! instead.
         
     | 
| 
       226 
372 
     | 
    
         
             
                def becomes(klass)
         
     | 
| 
       227 
     | 
    
         
            -
                  became = klass. 
     | 
| 
      
 373 
     | 
    
         
            +
                  became = klass.allocate
         
     | 
| 
      
 374 
     | 
    
         
            +
                  became.send(:initialize)
         
     | 
| 
       228 
375 
     | 
    
         
             
                  became.instance_variable_set("@attributes", @attributes)
         
     | 
| 
       229 
     | 
    
         
            -
                  became.instance_variable_set("@ 
     | 
| 
      
 376 
     | 
    
         
            +
                  became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
         
     | 
| 
       230 
377 
     | 
    
         
             
                  became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
         
     | 
| 
       231 
378 
     | 
    
         
             
                  became.instance_variable_set("@new_record", new_record?)
         
     | 
| 
       232 
379 
     | 
    
         
             
                  became.instance_variable_set("@destroyed", destroyed?)
         
     | 
| 
         @@ -326,13 +473,16 @@ module ActiveRecord 
     | 
|
| 
       326 
473 
     | 
    
         
             
                    verify_readonly_attribute(key.to_s)
         
     | 
| 
       327 
474 
     | 
    
         
             
                  end
         
     | 
| 
       328 
475 
     | 
    
         | 
| 
       329 
     | 
    
         
            -
                   
     | 
| 
      
 476 
     | 
    
         
            +
                  affected_rows = self.class._update_record(
         
     | 
| 
      
 477 
     | 
    
         
            +
                    attributes,
         
     | 
| 
      
 478 
     | 
    
         
            +
                    self.class.primary_key => id_in_database
         
     | 
| 
      
 479 
     | 
    
         
            +
                  )
         
     | 
| 
       330 
480 
     | 
    
         | 
| 
       331 
481 
     | 
    
         
             
                  attributes.each do |k, v|
         
     | 
| 
       332 
     | 
    
         
            -
                     
     | 
| 
      
 482 
     | 
    
         
            +
                    write_attribute_without_type_cast(k, v)
         
     | 
| 
       333 
483 
     | 
    
         
             
                  end
         
     | 
| 
       334 
484 
     | 
    
         | 
| 
       335 
     | 
    
         
            -
                   
     | 
| 
      
 485 
     | 
    
         
            +
                  affected_rows == 1
         
     | 
| 
       336 
486 
     | 
    
         
             
                end
         
     | 
| 
       337 
487 
     | 
    
         | 
| 
       338 
488 
     | 
    
         
             
                # Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
         
     | 
| 
         @@ -347,7 +497,7 @@ module ActiveRecord 
     | 
|
| 
       347 
497 
     | 
    
         
             
                # Wrapper around #increment that writes the update to the database.
         
     | 
| 
       348 
498 
     | 
    
         
             
                # Only +attribute+ is updated; the record itself is not saved.
         
     | 
| 
       349 
499 
     | 
    
         
             
                # This means that any other modified attributes will still be dirty.
         
     | 
| 
       350 
     | 
    
         
            -
                # Validations and callbacks are skipped. Supports the  
     | 
| 
      
 500 
     | 
    
         
            +
                # Validations and callbacks are skipped. Supports the +touch+ option from
         
     | 
| 
       351 
501 
     | 
    
         
             
                # +update_counters+, see that for more.
         
     | 
| 
       352 
502 
     | 
    
         
             
                # Returns +self+.
         
     | 
| 
       353 
503 
     | 
    
         
             
                def increment!(attribute, by = 1, touch: nil)
         
     | 
| 
         @@ -368,7 +518,7 @@ module ActiveRecord 
     | 
|
| 
       368 
518 
     | 
    
         
             
                # Wrapper around #decrement that writes the update to the database.
         
     | 
| 
       369 
519 
     | 
    
         
             
                # Only +attribute+ is updated; the record itself is not saved.
         
     | 
| 
       370 
520 
     | 
    
         
             
                # This means that any other modified attributes will still be dirty.
         
     | 
| 
       371 
     | 
    
         
            -
                # Validations and callbacks are skipped. Supports the  
     | 
| 
      
 521 
     | 
    
         
            +
                # Validations and callbacks are skipped. Supports the +touch+ option from
         
     | 
| 
       372 
522 
     | 
    
         
             
                # +update_counters+, see that for more.
         
     | 
| 
       373 
523 
     | 
    
         
             
                # Returns +self+.
         
     | 
| 
       374 
524 
     | 
    
         
             
                def decrement!(attribute, by = 1, touch: nil)
         
     | 
| 
         @@ -505,36 +655,12 @@ module ActiveRecord 
     | 
|
| 
       505 
655 
     | 
    
         
             
                    MSG
         
     | 
| 
       506 
656 
     | 
    
         
             
                  end
         
     | 
| 
       507 
657 
     | 
    
         | 
| 
       508 
     | 
    
         
            -
                   
     | 
| 
       509 
     | 
    
         
            -
                   
     | 
| 
       510 
     | 
    
         
            -
                  attributes.concat(names)
         
     | 
| 
       511 
     | 
    
         
            -
             
     | 
| 
       512 
     | 
    
         
            -
                  unless attributes.empty?
         
     | 
| 
       513 
     | 
    
         
            -
                    changes = {}
         
     | 
| 
       514 
     | 
    
         
            -
             
     | 
| 
       515 
     | 
    
         
            -
                    attributes.each do |column|
         
     | 
| 
       516 
     | 
    
         
            -
                      column = column.to_s
         
     | 
| 
       517 
     | 
    
         
            -
                      changes[column] = write_attribute(column, time)
         
     | 
| 
       518 
     | 
    
         
            -
                    end
         
     | 
| 
       519 
     | 
    
         
            -
             
     | 
| 
       520 
     | 
    
         
            -
                    primary_key = self.class.primary_key
         
     | 
| 
       521 
     | 
    
         
            -
                    scope = self.class.unscoped.where(primary_key => _read_attribute(primary_key))
         
     | 
| 
       522 
     | 
    
         
            -
             
     | 
| 
       523 
     | 
    
         
            -
                    if locking_enabled?
         
     | 
| 
       524 
     | 
    
         
            -
                      locking_column = self.class.locking_column
         
     | 
| 
       525 
     | 
    
         
            -
                      scope = scope.where(locking_column => _read_attribute(locking_column))
         
     | 
| 
       526 
     | 
    
         
            -
                      changes[locking_column] = increment_lock
         
     | 
| 
       527 
     | 
    
         
            -
                    end
         
     | 
| 
       528 
     | 
    
         
            -
             
     | 
| 
       529 
     | 
    
         
            -
                    clear_attribute_changes(changes.keys)
         
     | 
| 
       530 
     | 
    
         
            -
                    result = scope.update_all(changes) == 1
         
     | 
| 
       531 
     | 
    
         
            -
             
     | 
| 
       532 
     | 
    
         
            -
                    if !result && locking_enabled?
         
     | 
| 
       533 
     | 
    
         
            -
                      raise ActiveRecord::StaleObjectError.new(self, "touch")
         
     | 
| 
       534 
     | 
    
         
            -
                    end
         
     | 
| 
      
 658 
     | 
    
         
            +
                  attribute_names = timestamp_attributes_for_update_in_model
         
     | 
| 
      
 659 
     | 
    
         
            +
                  attribute_names |= names.map(&:to_s)
         
     | 
| 
       535 
660 
     | 
    
         | 
| 
       536 
     | 
    
         
            -
             
     | 
| 
       537 
     | 
    
         
            -
                     
     | 
| 
      
 661 
     | 
    
         
            +
                  unless attribute_names.empty?
         
     | 
| 
      
 662 
     | 
    
         
            +
                    affected_rows = _touch_row(attribute_names, time)
         
     | 
| 
      
 663 
     | 
    
         
            +
                    @_trigger_update_callback = affected_rows == 1
         
     | 
| 
       538 
664 
     | 
    
         
             
                  else
         
     | 
| 
       539 
665 
     | 
    
         
             
                    true
         
     | 
| 
       540 
666 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -547,15 +673,34 @@ module ActiveRecord 
     | 
|
| 
       547 
673 
     | 
    
         
             
                end
         
     | 
| 
       548 
674 
     | 
    
         | 
| 
       549 
675 
     | 
    
         
             
                def destroy_row
         
     | 
| 
       550 
     | 
    
         
            -
                   
     | 
| 
      
 676 
     | 
    
         
            +
                  _delete_row
         
     | 
| 
       551 
677 
     | 
    
         
             
                end
         
     | 
| 
       552 
678 
     | 
    
         | 
| 
       553 
     | 
    
         
            -
                def  
     | 
| 
       554 
     | 
    
         
            -
                  self.class. 
     | 
| 
      
 679 
     | 
    
         
            +
                def _delete_row
         
     | 
| 
      
 680 
     | 
    
         
            +
                  self.class._delete_record(self.class.primary_key => id_in_database)
         
     | 
| 
      
 681 
     | 
    
         
            +
                end
         
     | 
| 
      
 682 
     | 
    
         
            +
             
     | 
| 
      
 683 
     | 
    
         
            +
                def _touch_row(attribute_names, time)
         
     | 
| 
      
 684 
     | 
    
         
            +
                  time ||= current_time_from_proper_timezone
         
     | 
| 
      
 685 
     | 
    
         
            +
             
     | 
| 
      
 686 
     | 
    
         
            +
                  attribute_names.each do |attr_name|
         
     | 
| 
      
 687 
     | 
    
         
            +
                    write_attribute(attr_name, time)
         
     | 
| 
      
 688 
     | 
    
         
            +
                    clear_attribute_change(attr_name)
         
     | 
| 
      
 689 
     | 
    
         
            +
                  end
         
     | 
| 
      
 690 
     | 
    
         
            +
             
     | 
| 
      
 691 
     | 
    
         
            +
                  _update_row(attribute_names, "touch")
         
     | 
| 
      
 692 
     | 
    
         
            +
                end
         
     | 
| 
      
 693 
     | 
    
         
            +
             
     | 
| 
      
 694 
     | 
    
         
            +
                def _update_row(attribute_names, attempted_action = "update")
         
     | 
| 
      
 695 
     | 
    
         
            +
                  self.class._update_record(
         
     | 
| 
      
 696 
     | 
    
         
            +
                    attributes_with_values(attribute_names),
         
     | 
| 
      
 697 
     | 
    
         
            +
                    self.class.primary_key => id_in_database
         
     | 
| 
      
 698 
     | 
    
         
            +
                  )
         
     | 
| 
       555 
699 
     | 
    
         
             
                end
         
     | 
| 
       556 
700 
     | 
    
         | 
| 
       557 
701 
     | 
    
         
             
                def create_or_update(*args, &block)
         
     | 
| 
       558 
702 
     | 
    
         
             
                  _raise_readonly_record_error if readonly?
         
     | 
| 
      
 703 
     | 
    
         
            +
                  return false if destroyed?
         
     | 
| 
       559 
704 
     | 
    
         
             
                  result = new_record? ? _create_record(&block) : _update_record(*args, &block)
         
     | 
| 
       560 
705 
     | 
    
         
             
                  result != false
         
     | 
| 
       561 
706 
     | 
    
         
             
                end
         
     | 
| 
         @@ -563,26 +708,29 @@ module ActiveRecord 
     | 
|
| 
       563 
708 
     | 
    
         
             
                # Updates the associated record with values matching those of the instance attributes.
         
     | 
| 
       564 
709 
     | 
    
         
             
                # Returns the number of affected rows.
         
     | 
| 
       565 
710 
     | 
    
         
             
                def _update_record(attribute_names = self.attribute_names)
         
     | 
| 
       566 
     | 
    
         
            -
                   
     | 
| 
       567 
     | 
    
         
            -
                   
     | 
| 
       568 
     | 
    
         
            -
             
     | 
| 
      
 711 
     | 
    
         
            +
                  attribute_names &= self.class.column_names
         
     | 
| 
      
 712 
     | 
    
         
            +
                  attribute_names = attributes_for_update(attribute_names)
         
     | 
| 
      
 713 
     | 
    
         
            +
             
     | 
| 
      
 714 
     | 
    
         
            +
                  if attribute_names.empty?
         
     | 
| 
      
 715 
     | 
    
         
            +
                    affected_rows = 0
         
     | 
| 
       569 
716 
     | 
    
         
             
                    @_trigger_update_callback = true
         
     | 
| 
       570 
717 
     | 
    
         
             
                  else
         
     | 
| 
       571 
     | 
    
         
            -
                     
     | 
| 
       572 
     | 
    
         
            -
                    @_trigger_update_callback =  
     | 
| 
      
 718 
     | 
    
         
            +
                    affected_rows = _update_row(attribute_names)
         
     | 
| 
      
 719 
     | 
    
         
            +
                    @_trigger_update_callback = affected_rows == 1
         
     | 
| 
       573 
720 
     | 
    
         
             
                  end
         
     | 
| 
       574 
721 
     | 
    
         | 
| 
       575 
722 
     | 
    
         
             
                  yield(self) if block_given?
         
     | 
| 
       576 
723 
     | 
    
         | 
| 
       577 
     | 
    
         
            -
                   
     | 
| 
      
 724 
     | 
    
         
            +
                  affected_rows
         
     | 
| 
       578 
725 
     | 
    
         
             
                end
         
     | 
| 
       579 
726 
     | 
    
         | 
| 
       580 
727 
     | 
    
         
             
                # Creates a record with values matching those of the instance attributes
         
     | 
| 
       581 
728 
     | 
    
         
             
                # and returns its id.
         
     | 
| 
       582 
729 
     | 
    
         
             
                def _create_record(attribute_names = self.attribute_names)
         
     | 
| 
       583 
     | 
    
         
            -
                   
     | 
| 
      
 730 
     | 
    
         
            +
                  attribute_names &= self.class.column_names
         
     | 
| 
      
 731 
     | 
    
         
            +
                  attributes_values = attributes_with_values_for_create(attribute_names)
         
     | 
| 
       584 
732 
     | 
    
         | 
| 
       585 
     | 
    
         
            -
                  new_id = self.class. 
     | 
| 
      
 733 
     | 
    
         
            +
                  new_id = self.class._insert_record(attributes_values)
         
     | 
| 
       586 
734 
     | 
    
         
             
                  self.id ||= new_id if self.class.primary_key
         
     | 
| 
       587 
735 
     | 
    
         | 
| 
       588 
736 
     | 
    
         
             
                  @new_record = false
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       2 
4 
     | 
    
         
             
              # = Active Record Query Cache
         
     | 
| 
       3 
5 
     | 
    
         
             
              class QueryCache
         
     | 
| 
         @@ -5,35 +7,31 @@ module ActiveRecord 
     | 
|
| 
       5 
7 
     | 
    
         
             
                  # Enable the query cache within the block if Active Record is configured.
         
     | 
| 
       6 
8 
     | 
    
         
             
                  # If it's not, it will execute the given block.
         
     | 
| 
       7 
9 
     | 
    
         
             
                  def cache(&block)
         
     | 
| 
       8 
     | 
    
         
            -
                    if configurations.empty?
         
     | 
| 
       9 
     | 
    
         
            -
                      yield
         
     | 
| 
       10 
     | 
    
         
            -
                    else
         
     | 
| 
      
 10 
     | 
    
         
            +
                    if connected? || !configurations.empty?
         
     | 
| 
       11 
11 
     | 
    
         
             
                      connection.cache(&block)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    else
         
     | 
| 
      
 13 
     | 
    
         
            +
                      yield
         
     | 
| 
       12 
14 
     | 
    
         
             
                    end
         
     | 
| 
       13 
15 
     | 
    
         
             
                  end
         
     | 
| 
       14 
16 
     | 
    
         | 
| 
       15 
17 
     | 
    
         
             
                  # Disable the query cache within the block if Active Record is configured.
         
     | 
| 
       16 
18 
     | 
    
         
             
                  # If it's not, it will execute the given block.
         
     | 
| 
       17 
19 
     | 
    
         
             
                  def uncached(&block)
         
     | 
| 
       18 
     | 
    
         
            -
                    if configurations.empty?
         
     | 
| 
       19 
     | 
    
         
            -
                      yield
         
     | 
| 
       20 
     | 
    
         
            -
                    else
         
     | 
| 
      
 20 
     | 
    
         
            +
                    if connected? || !configurations.empty?
         
     | 
| 
       21 
21 
     | 
    
         
             
                      connection.uncached(&block)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    else
         
     | 
| 
      
 23 
     | 
    
         
            +
                      yield
         
     | 
| 
       22 
24 
     | 
    
         
             
                    end
         
     | 
| 
       23 
25 
     | 
    
         
             
                  end
         
     | 
| 
       24 
26 
     | 
    
         
             
                end
         
     | 
| 
       25 
27 
     | 
    
         | 
| 
       26 
28 
     | 
    
         
             
                def self.run
         
     | 
| 
       27 
     | 
    
         
            -
                   
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                  caching_pool.enable_query_cache!
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                  [caching_pool, caching_was_enabled]
         
     | 
| 
      
 29 
     | 
    
         
            +
                  ActiveRecord::Base.connection_handler.connection_pool_list.
         
     | 
| 
      
 30 
     | 
    
         
            +
                    reject { |p| p.query_cache_enabled }.each { |p| p.enable_query_cache! }
         
     | 
| 
       33 
31 
     | 
    
         
             
                end
         
     | 
| 
       34 
32 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                def self.complete( 
     | 
| 
       36 
     | 
    
         
            -
                   
     | 
| 
      
 33 
     | 
    
         
            +
                def self.complete(pools)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  pools.each { |pool| pool.disable_query_cache! }
         
     | 
| 
       37 
35 
     | 
    
         | 
| 
       38 
36 
     | 
    
         
             
                  ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
         
     | 
| 
       39 
37 
     | 
    
         
             
                    pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       2 
4 
     | 
    
         
             
              module Querying
         
     | 
| 
       3 
5 
     | 
    
         
             
                delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all
         
     | 
| 
         @@ -5,7 +7,7 @@ module ActiveRecord 
     | 
|
| 
       5 
7 
     | 
    
         
             
                delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
         
     | 
| 
       6 
8 
     | 
    
         
             
                delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
         
     | 
| 
       7 
9 
     | 
    
         
             
                delegate :find_by, :find_by!, to: :all
         
     | 
| 
       8 
     | 
    
         
            -
                delegate : 
     | 
| 
      
 10 
     | 
    
         
            +
                delegate :destroy_all, :delete_all, :update_all, to: :all
         
     | 
| 
       9 
11 
     | 
    
         
             
                delegate :find_each, :find_in_batches, :in_batches, to: :all
         
     | 
| 
       10 
12 
     | 
    
         
             
                delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
         
     | 
| 
       11 
13 
     | 
    
         
             
                         :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require "active_record"
         
     | 
| 
       2 
4 
     | 
    
         
             
            require "rails"
         
     | 
| 
       3 
5 
     | 
    
         
             
            require "active_model/railtie"
         
     | 
| 
         @@ -26,6 +28,9 @@ module ActiveRecord 
     | 
|
| 
       26 
28 
     | 
    
         
             
                config.active_record.use_schema_cache_dump = true
         
     | 
| 
       27 
29 
     | 
    
         
             
                config.active_record.maintain_test_schema = true
         
     | 
| 
       28 
30 
     | 
    
         | 
| 
      
 31 
     | 
    
         
            +
                config.active_record.sqlite3 = ActiveSupport::OrderedOptions.new
         
     | 
| 
      
 32 
     | 
    
         
            +
                config.active_record.sqlite3.represent_boolean_as_integer = nil
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       29 
34 
     | 
    
         
             
                config.eager_load_namespaces << ActiveRecord
         
     | 
| 
       30 
35 
     | 
    
         | 
| 
       31 
36 
     | 
    
         
             
                rake_tasks do
         
     | 
| 
         @@ -54,6 +59,7 @@ module ActiveRecord 
     | 
|
| 
       54 
59 
     | 
    
         
             
                    console = ActiveSupport::Logger.new(STDERR)
         
     | 
| 
       55 
60 
     | 
    
         
             
                    Rails.logger.extend ActiveSupport::Logger.broadcast console
         
     | 
| 
       56 
61 
     | 
    
         
             
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  ActiveRecord::Base.verbose_query_logs = false
         
     | 
| 
       57 
63 
     | 
    
         
             
                end
         
     | 
| 
       58 
64 
     | 
    
         | 
| 
       59 
65 
     | 
    
         
             
                runner do
         
     | 
| 
         @@ -85,12 +91,16 @@ module ActiveRecord 
     | 
|
| 
       85 
91 
     | 
    
         
             
                        filename = File.join(app.config.paths["db"].first, "schema_cache.yml")
         
     | 
| 
       86 
92 
     | 
    
         | 
| 
       87 
93 
     | 
    
         
             
                        if File.file?(filename)
         
     | 
| 
      
 94 
     | 
    
         
            +
                          current_version = ActiveRecord::Migrator.current_version
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                          next if current_version.nil?
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
       88 
98 
     | 
    
         
             
                          cache = YAML.load(File.read(filename))
         
     | 
| 
       89 
     | 
    
         
            -
                          if cache.version ==  
     | 
| 
      
 99 
     | 
    
         
            +
                          if cache.version == current_version
         
     | 
| 
       90 
100 
     | 
    
         
             
                            connection.schema_cache = cache
         
     | 
| 
       91 
101 
     | 
    
         
             
                            connection_pool.schema_cache = cache.dup
         
     | 
| 
       92 
102 
     | 
    
         
             
                          else
         
     | 
| 
       93 
     | 
    
         
            -
                            warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{ 
     | 
| 
      
 103 
     | 
    
         
            +
                            warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
         
     | 
| 
       94 
104 
     | 
    
         
             
                          end
         
     | 
| 
       95 
105 
     | 
    
         
             
                        end
         
     | 
| 
       96 
106 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -108,7 +118,9 @@ module ActiveRecord 
     | 
|
| 
       108 
118 
     | 
    
         | 
| 
       109 
119 
     | 
    
         
             
                initializer "active_record.set_configs" do |app|
         
     | 
| 
       110 
120 
     | 
    
         
             
                  ActiveSupport.on_load(:active_record) do
         
     | 
| 
       111 
     | 
    
         
            -
                    app.config.active_record. 
     | 
| 
      
 121 
     | 
    
         
            +
                    configs = app.config.active_record.dup
         
     | 
| 
      
 122 
     | 
    
         
            +
                    configs.delete(:sqlite3)
         
     | 
| 
      
 123 
     | 
    
         
            +
                    configs.each do |k, v|
         
     | 
| 
       112 
124 
     | 
    
         
             
                      send "#{k}=", v
         
     | 
| 
       113 
125 
     | 
    
         
             
                    end
         
     | 
| 
       114 
126 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -166,5 +178,51 @@ end_warning 
     | 
|
| 
       166 
178 
     | 
    
         
             
                  path = app.paths["db"].first
         
     | 
| 
       167 
179 
     | 
    
         
             
                  config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
         
     | 
| 
       168 
180 
     | 
    
         
             
                end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                initializer "active_record.clear_active_connections" do
         
     | 
| 
      
 183 
     | 
    
         
            +
                  config.after_initialize do
         
     | 
| 
      
 184 
     | 
    
         
            +
                    ActiveSupport.on_load(:active_record) do
         
     | 
| 
      
 185 
     | 
    
         
            +
                      # Ideally the application doesn't connect to the database during boot,
         
     | 
| 
      
 186 
     | 
    
         
            +
                      # but sometimes it does. In case it did, we want to empty out the
         
     | 
| 
      
 187 
     | 
    
         
            +
                      # connection pools so that a non-database-using process (e.g. a master
         
     | 
| 
      
 188 
     | 
    
         
            +
                      # process in a forking server model) doesn't retain a needless
         
     | 
| 
      
 189 
     | 
    
         
            +
                      # connection. If it was needed, the incremental cost of reestablishing
         
     | 
| 
      
 190 
     | 
    
         
            +
                      # this connection is trivial: the rest of the pool would need to be
         
     | 
| 
      
 191 
     | 
    
         
            +
                      # populated anyway.
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                      clear_active_connections!
         
     | 
| 
      
 194 
     | 
    
         
            +
                      flush_idle_connections!
         
     | 
| 
      
 195 
     | 
    
         
            +
                    end
         
     | 
| 
      
 196 
     | 
    
         
            +
                  end
         
     | 
| 
      
 197 
     | 
    
         
            +
                end
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                initializer "active_record.check_represent_sqlite3_boolean_as_integer" do
         
     | 
| 
      
 200 
     | 
    
         
            +
                  config.after_initialize do
         
     | 
| 
      
 201 
     | 
    
         
            +
                    ActiveSupport.on_load(:active_record_sqlite3adapter) do
         
     | 
| 
      
 202 
     | 
    
         
            +
                      represent_boolean_as_integer = Rails.application.config.active_record.sqlite3.delete(:represent_boolean_as_integer)
         
     | 
| 
      
 203 
     | 
    
         
            +
                      unless represent_boolean_as_integer.nil?
         
     | 
| 
      
 204 
     | 
    
         
            +
                        ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
         
     | 
| 
      
 205 
     | 
    
         
            +
                      end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                      unless ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer
         
     | 
| 
      
 208 
     | 
    
         
            +
                        ActiveSupport::Deprecation.warn <<-MSG
         
     | 
| 
      
 209 
     | 
    
         
            +
            Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
         
     | 
| 
      
 210 
     | 
    
         
            +
            set to false is deprecated. SQLite databases have used 't' and 'f' to serialize
         
     | 
| 
      
 211 
     | 
    
         
            +
            boolean values and must have old data converted to 1 and 0 (its native boolean
         
     | 
| 
      
 212 
     | 
    
         
            +
            serialization) before setting this flag to true. Conversion can be accomplished
         
     | 
| 
      
 213 
     | 
    
         
            +
            by setting up a rake task which runs
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
              ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
         
     | 
| 
      
 216 
     | 
    
         
            +
              ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
            for all models and all boolean columns, after which the flag must be set to
         
     | 
| 
      
 219 
     | 
    
         
            +
            true by adding the following to your application.rb file:
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
              Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
         
     | 
| 
      
 222 
     | 
    
         
            +
            MSG
         
     | 
| 
      
 223 
     | 
    
         
            +
                      end
         
     | 
| 
      
 224 
     | 
    
         
            +
                    end
         
     | 
| 
      
 225 
     | 
    
         
            +
                  end
         
     | 
| 
      
 226 
     | 
    
         
            +
                end
         
     | 
| 
       169 
227 
     | 
    
         
             
              end
         
     | 
| 
       170 
228 
     | 
    
         
             
            end
         
     |