activerecord 4.2.11.3 → 5.0.7.2
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 +1638 -1132
 - data/MIT-LICENSE +2 -2
 - data/README.rdoc +7 -8
 - data/examples/performance.rb +2 -3
 - data/examples/simple.rb +0 -1
 - data/lib/active_record.rb +7 -2
 - data/lib/active_record/aggregations.rb +34 -21
 - data/lib/active_record/association_relation.rb +7 -4
 - data/lib/active_record/associations.rb +347 -218
 - data/lib/active_record/associations/alias_tracker.rb +19 -16
 - data/lib/active_record/associations/association.rb +22 -10
 - data/lib/active_record/associations/association_scope.rb +75 -104
 - data/lib/active_record/associations/belongs_to_association.rb +21 -32
 - data/lib/active_record/associations/builder/association.rb +28 -34
 - data/lib/active_record/associations/builder/belongs_to.rb +43 -18
 - data/lib/active_record/associations/builder/collection_association.rb +7 -19
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +16 -11
 - data/lib/active_record/associations/builder/has_many.rb +4 -4
 - data/lib/active_record/associations/builder/has_one.rb +11 -6
 - data/lib/active_record/associations/builder/singular_association.rb +13 -11
 - data/lib/active_record/associations/collection_association.rb +85 -69
 - data/lib/active_record/associations/collection_proxy.rb +104 -46
 - data/lib/active_record/associations/foreign_association.rb +1 -1
 - data/lib/active_record/associations/has_many_association.rb +21 -78
 - data/lib/active_record/associations/has_many_through_association.rb +6 -47
 - data/lib/active_record/associations/has_one_association.rb +12 -5
 - data/lib/active_record/associations/join_dependency.rb +38 -22
 - data/lib/active_record/associations/join_dependency/join_association.rb +15 -14
 - data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
 - data/lib/active_record/associations/preloader.rb +14 -4
 - data/lib/active_record/associations/preloader/association.rb +52 -71
 - data/lib/active_record/associations/preloader/collection_association.rb +0 -7
 - data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
 - data/lib/active_record/associations/preloader/has_one.rb +0 -8
 - data/lib/active_record/associations/preloader/singular_association.rb +0 -1
 - data/lib/active_record/associations/preloader/through_association.rb +36 -17
 - data/lib/active_record/associations/singular_association.rb +13 -1
 - data/lib/active_record/associations/through_association.rb +12 -4
 - data/lib/active_record/attribute.rb +69 -19
 - data/lib/active_record/attribute/user_provided_default.rb +28 -0
 - data/lib/active_record/attribute_assignment.rb +19 -140
 - data/lib/active_record/attribute_decorators.rb +6 -5
 - data/lib/active_record/attribute_methods.rb +69 -44
 - data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
 - data/lib/active_record/attribute_methods/dirty.rb +46 -86
 - data/lib/active_record/attribute_methods/primary_key.rb +16 -3
 - data/lib/active_record/attribute_methods/query.rb +2 -2
 - data/lib/active_record/attribute_methods/read.rb +31 -59
 - data/lib/active_record/attribute_methods/serialization.rb +13 -16
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -14
 - data/lib/active_record/attribute_methods/write.rb +13 -37
 - data/lib/active_record/attribute_mutation_tracker.rb +70 -0
 - data/lib/active_record/attribute_set.rb +32 -3
 - data/lib/active_record/attribute_set/builder.rb +42 -16
 - data/lib/active_record/attributes.rb +199 -81
 - data/lib/active_record/autosave_association.rb +54 -17
 - data/lib/active_record/base.rb +32 -23
 - data/lib/active_record/callbacks.rb +39 -43
 - data/lib/active_record/coders/json.rb +1 -1
 - data/lib/active_record/coders/yaml_column.rb +20 -8
 - data/lib/active_record/collection_cache_key.rb +50 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +467 -189
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -62
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +39 -4
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +86 -13
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -188
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +407 -156
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +51 -34
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -71
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +433 -399
 - data/lib/active_record/connection_adapters/column.rb +28 -43
 - data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
 - data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +108 -0
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +25 -166
 - data/lib/active_record/connection_adapters/postgresql/column.rb +33 -11
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -72
 - data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +37 -57
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +3 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +13 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
 - data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
 - data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +56 -19
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
 - data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +250 -154
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +264 -170
 - data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
 - data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +151 -194
 - data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
 - data/lib/active_record/connection_handling.rb +37 -14
 - data/lib/active_record/core.rb +92 -108
 - data/lib/active_record/counter_cache.rb +13 -24
 - data/lib/active_record/dynamic_matchers.rb +1 -20
 - data/lib/active_record/enum.rb +116 -76
 - data/lib/active_record/errors.rb +87 -48
 - data/lib/active_record/explain.rb +20 -9
 - data/lib/active_record/explain_registry.rb +1 -1
 - data/lib/active_record/explain_subscriber.rb +1 -1
 - data/lib/active_record/fixture_set/file.rb +26 -5
 - data/lib/active_record/fixtures.rb +77 -41
 - data/lib/active_record/gem_version.rb +4 -4
 - data/lib/active_record/inheritance.rb +32 -40
 - data/lib/active_record/integration.rb +17 -14
 - data/lib/active_record/internal_metadata.rb +56 -0
 - data/lib/active_record/legacy_yaml_adapter.rb +18 -2
 - data/lib/active_record/locale/en.yml +3 -2
 - data/lib/active_record/locking/optimistic.rb +15 -15
 - data/lib/active_record/locking/pessimistic.rb +1 -1
 - data/lib/active_record/log_subscriber.rb +48 -24
 - data/lib/active_record/migration.rb +362 -111
 - data/lib/active_record/migration/command_recorder.rb +59 -18
 - data/lib/active_record/migration/compatibility.rb +126 -0
 - data/lib/active_record/model_schema.rb +270 -73
 - data/lib/active_record/nested_attributes.rb +58 -29
 - data/lib/active_record/no_touching.rb +4 -0
 - data/lib/active_record/null_relation.rb +16 -8
 - data/lib/active_record/persistence.rb +152 -90
 - data/lib/active_record/query_cache.rb +18 -23
 - data/lib/active_record/querying.rb +12 -11
 - data/lib/active_record/railtie.rb +23 -16
 - data/lib/active_record/railties/controller_runtime.rb +1 -1
 - data/lib/active_record/railties/databases.rake +52 -41
 - data/lib/active_record/readonly_attributes.rb +1 -1
 - data/lib/active_record/reflection.rb +302 -115
 - data/lib/active_record/relation.rb +187 -120
 - data/lib/active_record/relation/batches.rb +141 -36
 - data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
 - data/lib/active_record/relation/calculations.rb +92 -117
 - data/lib/active_record/relation/delegation.rb +8 -20
 - data/lib/active_record/relation/finder_methods.rb +173 -89
 - data/lib/active_record/relation/from_clause.rb +32 -0
 - data/lib/active_record/relation/merger.rb +16 -42
 - data/lib/active_record/relation/predicate_builder.rb +120 -107
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
 - data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
 - data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
 - data/lib/active_record/relation/query_attribute.rb +19 -0
 - data/lib/active_record/relation/query_methods.rb +308 -244
 - data/lib/active_record/relation/record_fetch_warning.rb +49 -0
 - data/lib/active_record/relation/spawn_methods.rb +4 -7
 - data/lib/active_record/relation/where_clause.rb +174 -0
 - data/lib/active_record/relation/where_clause_factory.rb +38 -0
 - data/lib/active_record/result.rb +11 -4
 - data/lib/active_record/runtime_registry.rb +1 -1
 - data/lib/active_record/sanitization.rb +105 -66
 - data/lib/active_record/schema.rb +26 -22
 - data/lib/active_record/schema_dumper.rb +54 -37
 - data/lib/active_record/schema_migration.rb +11 -14
 - data/lib/active_record/scoping.rb +34 -16
 - data/lib/active_record/scoping/default.rb +28 -10
 - data/lib/active_record/scoping/named.rb +59 -26
 - data/lib/active_record/secure_token.rb +38 -0
 - data/lib/active_record/serialization.rb +3 -5
 - data/lib/active_record/statement_cache.rb +17 -15
 - data/lib/active_record/store.rb +8 -3
 - data/lib/active_record/suppressor.rb +58 -0
 - data/lib/active_record/table_metadata.rb +69 -0
 - data/lib/active_record/tasks/database_tasks.rb +66 -49
 - data/lib/active_record/tasks/mysql_database_tasks.rb +6 -14
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +12 -3
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
 - data/lib/active_record/timestamp.rb +20 -9
 - data/lib/active_record/touch_later.rb +63 -0
 - data/lib/active_record/transactions.rb +139 -57
 - data/lib/active_record/type.rb +66 -17
 - data/lib/active_record/type/adapter_specific_registry.rb +130 -0
 - data/lib/active_record/type/date.rb +2 -45
 - data/lib/active_record/type/date_time.rb +2 -49
 - data/lib/active_record/type/internal/abstract_json.rb +33 -0
 - data/lib/active_record/type/internal/timezone.rb +15 -0
 - data/lib/active_record/type/serialized.rb +15 -14
 - data/lib/active_record/type/time.rb +10 -16
 - data/lib/active_record/type/type_map.rb +4 -4
 - data/lib/active_record/type_caster.rb +7 -0
 - data/lib/active_record/type_caster/connection.rb +29 -0
 - data/lib/active_record/type_caster/map.rb +19 -0
 - data/lib/active_record/validations.rb +33 -32
 - data/lib/active_record/validations/absence.rb +23 -0
 - data/lib/active_record/validations/associated.rb +10 -3
 - data/lib/active_record/validations/length.rb +24 -0
 - data/lib/active_record/validations/presence.rb +11 -12
 - data/lib/active_record/validations/uniqueness.rb +33 -33
 - data/lib/rails/generators/active_record/migration.rb +15 -0
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -5
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
 - data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -1
 - data/lib/rails/generators/active_record/model/model_generator.rb +33 -16
 - data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
 - data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
 - metadata +58 -34
 - data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
 - data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
 - data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
 - data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
 - data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
 - data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
 - data/lib/active_record/serializers/xml_serializer.rb +0 -193
 - data/lib/active_record/type/big_integer.rb +0 -13
 - data/lib/active_record/type/binary.rb +0 -50
 - data/lib/active_record/type/boolean.rb +0 -31
 - data/lib/active_record/type/decimal.rb +0 -64
 - data/lib/active_record/type/decimal_without_scale.rb +0 -11
 - data/lib/active_record/type/decorator.rb +0 -14
 - data/lib/active_record/type/float.rb +0 -19
 - data/lib/active_record/type/integer.rb +0 -59
 - data/lib/active_record/type/mutable.rb +0 -16
 - data/lib/active_record/type/numeric.rb +0 -36
 - data/lib/active_record/type/string.rb +0 -40
 - data/lib/active_record/type/text.rb +0 -11
 - data/lib/active_record/type/time_value.rb +0 -38
 - data/lib/active_record/type/unsigned_integer.rb +0 -15
 - data/lib/active_record/type/value.rb +0 -110
 
| 
         @@ -5,7 +5,7 @@ module ActiveRecord 
     | 
|
| 
       5 
5 
     | 
    
         
             
                class DatabaseAlreadyExists < StandardError; end # :nodoc:
         
     | 
| 
       6 
6 
     | 
    
         
             
                class DatabaseNotSupported < StandardError; end # :nodoc:
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                #  
     | 
| 
      
 8 
     | 
    
         
            +
                # ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates
         
     | 
| 
       9 
9 
     | 
    
         
             
                # logic behind common tasks used to manage database and migrations.
         
     | 
| 
       10 
10 
     | 
    
         
             
                #
         
     | 
| 
       11 
11 
     | 
    
         
             
                # The tasks defined here are used with Rake tasks provided by Active Record.
         
     | 
| 
         @@ -18,15 +18,15 @@ module ActiveRecord 
     | 
|
| 
       18 
18 
     | 
    
         
             
                #
         
     | 
| 
       19 
19 
     | 
    
         
             
                # The possible config values are:
         
     | 
| 
       20 
20 
     | 
    
         
             
                #
         
     | 
| 
       21 
     | 
    
         
            -
                # 
     | 
| 
       22 
     | 
    
         
            -
                # 
     | 
| 
       23 
     | 
    
         
            -
                # 
     | 
| 
       24 
     | 
    
         
            -
                # 
     | 
| 
       25 
     | 
    
         
            -
                # 
     | 
| 
       26 
     | 
    
         
            -
                # 
     | 
| 
       27 
     | 
    
         
            -
                # 
     | 
| 
      
 21 
     | 
    
         
            +
                # * +env+: current environment (like Rails.env).
         
     | 
| 
      
 22 
     | 
    
         
            +
                # * +database_configuration+: configuration of your databases (as in +config/database.yml+).
         
     | 
| 
      
 23 
     | 
    
         
            +
                # * +db_dir+: your +db+ directory.
         
     | 
| 
      
 24 
     | 
    
         
            +
                # * +fixtures_path+: a path to fixtures directory.
         
     | 
| 
      
 25 
     | 
    
         
            +
                # * +migrations_paths+: a list of paths to directories with migrations.
         
     | 
| 
      
 26 
     | 
    
         
            +
                # * +seed_loader+: an object which will load seeds, it needs to respond to the +load_seed+ method.
         
     | 
| 
      
 27 
     | 
    
         
            +
                # * +root+: a path to the root of the application.
         
     | 
| 
       28 
28 
     | 
    
         
             
                #
         
     | 
| 
       29 
     | 
    
         
            -
                # Example usage of  
     | 
| 
      
 29 
     | 
    
         
            +
                # Example usage of DatabaseTasks outside Rails could look as such:
         
     | 
| 
       30 
30 
     | 
    
         
             
                #
         
     | 
| 
       31 
31 
     | 
    
         
             
                #   include ActiveRecord::Tasks
         
     | 
| 
       32 
32 
     | 
    
         
             
                #   DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml')
         
     | 
| 
         @@ -42,6 +42,22 @@ module ActiveRecord 
     | 
|
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
                  LOCAL_HOSTS    = ['127.0.0.1', 'localhost']
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
      
 45 
     | 
    
         
            +
                  def check_protected_environments!
         
     | 
| 
      
 46 
     | 
    
         
            +
                    unless ENV['DISABLE_DATABASE_ENVIRONMENT_CHECK']
         
     | 
| 
      
 47 
     | 
    
         
            +
                      current = ActiveRecord::Migrator.current_environment
         
     | 
| 
      
 48 
     | 
    
         
            +
                      stored  = ActiveRecord::Migrator.last_stored_environment
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                      if ActiveRecord::Migrator.protected_environment?
         
     | 
| 
      
 51 
     | 
    
         
            +
                        raise ActiveRecord::ProtectedEnvironmentError.new(stored)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                      if stored && stored != current
         
     | 
| 
      
 55 
     | 
    
         
            +
                        raise ActiveRecord::EnvironmentMismatchError.new(current: current, stored: stored)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      end
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  rescue ActiveRecord::NoDatabaseError
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
       45 
61 
     | 
    
         
             
                  def register_task(pattern, task)
         
     | 
| 
       46 
62 
     | 
    
         
             
                    @tasks ||= {}
         
     | 
| 
       47 
63 
     | 
    
         
             
                    @tasks[pattern] = task
         
     | 
| 
         @@ -91,15 +107,21 @@ module ActiveRecord 
     | 
|
| 
       91 
107 
     | 
    
         
             
                  def create(*arguments)
         
     | 
| 
       92 
108 
     | 
    
         
             
                    configuration = arguments.first
         
     | 
| 
       93 
109 
     | 
    
         
             
                    class_for_adapter(configuration['adapter']).new(*arguments).create
         
     | 
| 
      
 110 
     | 
    
         
            +
                    $stdout.puts "Created database '#{configuration['database']}'"
         
     | 
| 
       94 
111 
     | 
    
         
             
                  rescue DatabaseAlreadyExists
         
     | 
| 
       95 
     | 
    
         
            -
                    $stderr.puts "#{configuration['database']} already exists"
         
     | 
| 
      
 112 
     | 
    
         
            +
                    $stderr.puts "Database '#{configuration['database']}' already exists"
         
     | 
| 
       96 
113 
     | 
    
         
             
                  rescue Exception => error
         
     | 
| 
       97 
     | 
    
         
            -
                    $stderr.puts error 
     | 
| 
      
 114 
     | 
    
         
            +
                    $stderr.puts error
         
     | 
| 
       98 
115 
     | 
    
         
             
                    $stderr.puts "Couldn't create database for #{configuration.inspect}"
         
     | 
| 
      
 116 
     | 
    
         
            +
                    raise
         
     | 
| 
       99 
117 
     | 
    
         
             
                  end
         
     | 
| 
       100 
118 
     | 
    
         | 
| 
       101 
119 
     | 
    
         
             
                  def create_all
         
     | 
| 
      
 120 
     | 
    
         
            +
                    old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
         
     | 
| 
       102 
121 
     | 
    
         
             
                    each_local_configuration { |configuration| create configuration }
         
     | 
| 
      
 122 
     | 
    
         
            +
                    if old_pool
         
     | 
| 
      
 123 
     | 
    
         
            +
                      ActiveRecord::Base.connection_handler.establish_connection(old_pool.spec)
         
     | 
| 
      
 124 
     | 
    
         
            +
                    end
         
     | 
| 
       103 
125 
     | 
    
         
             
                  end
         
     | 
| 
       104 
126 
     | 
    
         | 
| 
       105 
127 
     | 
    
         
             
                  def create_current(environment = env)
         
     | 
| 
         @@ -112,11 +134,13 @@ module ActiveRecord 
     | 
|
| 
       112 
134 
     | 
    
         
             
                  def drop(*arguments)
         
     | 
| 
       113 
135 
     | 
    
         
             
                    configuration = arguments.first
         
     | 
| 
       114 
136 
     | 
    
         
             
                    class_for_adapter(configuration['adapter']).new(*arguments).drop
         
     | 
| 
      
 137 
     | 
    
         
            +
                    $stdout.puts "Dropped database '#{configuration['database']}'"
         
     | 
| 
       115 
138 
     | 
    
         
             
                  rescue ActiveRecord::NoDatabaseError
         
     | 
| 
       116 
139 
     | 
    
         
             
                    $stderr.puts "Database '#{configuration['database']}' does not exist"
         
     | 
| 
       117 
140 
     | 
    
         
             
                  rescue Exception => error
         
     | 
| 
       118 
     | 
    
         
            -
                    $stderr.puts error 
     | 
| 
       119 
     | 
    
         
            -
                    $stderr.puts "Couldn't drop #{configuration['database']}"
         
     | 
| 
      
 141 
     | 
    
         
            +
                    $stderr.puts error
         
     | 
| 
      
 142 
     | 
    
         
            +
                    $stderr.puts "Couldn't drop database '#{configuration['database']}'"
         
     | 
| 
      
 143 
     | 
    
         
            +
                    raise
         
     | 
| 
       120 
144 
     | 
    
         
             
                  end
         
     | 
| 
       121 
145 
     | 
    
         | 
| 
       122 
146 
     | 
    
         
             
                  def drop_all
         
     | 
| 
         @@ -191,59 +215,52 @@ module ActiveRecord 
     | 
|
| 
       191 
215 
     | 
    
         
             
                    class_for_adapter(configuration['adapter']).new(*arguments).structure_load(filename)
         
     | 
| 
       192 
216 
     | 
    
         
             
                  end
         
     | 
| 
       193 
217 
     | 
    
         | 
| 
       194 
     | 
    
         
            -
                  def load_schema(format = ActiveRecord::Base.schema_format, file = nil)
         
     | 
| 
       195 
     | 
    
         
            -
                    ActiveSupport::Deprecation.warn(<<-MSG.squish)
         
     | 
| 
       196 
     | 
    
         
            -
                      This method will act on a specific connection in the future.
         
     | 
| 
       197 
     | 
    
         
            -
                      To act on the current connection, use `load_schema_current` instead.
         
     | 
| 
       198 
     | 
    
         
            -
                    MSG
         
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
                    load_schema_current(format, file)
         
     | 
| 
       201 
     | 
    
         
            -
                  end
         
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
                  def schema_file(format = ActiveRecord::Base.schema_format)
         
     | 
| 
       204 
     | 
    
         
            -
                    case format
         
     | 
| 
       205 
     | 
    
         
            -
                    when :ruby
         
     | 
| 
       206 
     | 
    
         
            -
                      File.join(db_dir, "schema.rb")
         
     | 
| 
       207 
     | 
    
         
            -
                    when :sql
         
     | 
| 
       208 
     | 
    
         
            -
                      File.join(db_dir, "structure.sql")
         
     | 
| 
       209 
     | 
    
         
            -
                    end
         
     | 
| 
       210 
     | 
    
         
            -
                  end
         
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
       212 
     | 
    
         
            -
                  # This method is the successor of +load_schema+. We should rename it
         
     | 
| 
       213 
     | 
    
         
            -
                  # after +load_schema+ went through a deprecation cycle. (Rails > 4.2)
         
     | 
| 
       214 
     | 
    
         
            -
                  def load_schema_for(configuration, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
         
     | 
| 
      
 218 
     | 
    
         
            +
                  def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env) # :nodoc:
         
     | 
| 
       215 
219 
     | 
    
         
             
                    file ||= schema_file(format)
         
     | 
| 
       216 
220 
     | 
    
         | 
| 
      
 221 
     | 
    
         
            +
                    check_schema_file(file)
         
     | 
| 
      
 222 
     | 
    
         
            +
                    ActiveRecord::Base.establish_connection(configuration)
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
       217 
224 
     | 
    
         
             
                    case format
         
     | 
| 
       218 
225 
     | 
    
         
             
                    when :ruby
         
     | 
| 
       219 
     | 
    
         
            -
                      check_schema_file(file)
         
     | 
| 
       220 
     | 
    
         
            -
                      ActiveRecord::Base.establish_connection(configuration)
         
     | 
| 
       221 
226 
     | 
    
         
             
                      load(file)
         
     | 
| 
       222 
227 
     | 
    
         
             
                    when :sql
         
     | 
| 
       223 
     | 
    
         
            -
                      check_schema_file(file)
         
     | 
| 
       224 
228 
     | 
    
         
             
                      structure_load(configuration, file)
         
     | 
| 
       225 
229 
     | 
    
         
             
                    else
         
     | 
| 
       226 
230 
     | 
    
         
             
                      raise ArgumentError, "unknown format #{format.inspect}"
         
     | 
| 
       227 
231 
     | 
    
         
             
                    end
         
     | 
| 
      
 232 
     | 
    
         
            +
                    ActiveRecord::InternalMetadata.create_table
         
     | 
| 
      
 233 
     | 
    
         
            +
                    ActiveRecord::InternalMetadata[:environment] = environment
         
     | 
| 
      
 234 
     | 
    
         
            +
                  end
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
                  def load_schema_for(*args)
         
     | 
| 
      
 237 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn(<<-MSG.squish)
         
     | 
| 
      
 238 
     | 
    
         
            +
                      This method was renamed to `#load_schema` and will be removed in the future.
         
     | 
| 
      
 239 
     | 
    
         
            +
                      Use `#load_schema` instead.
         
     | 
| 
      
 240 
     | 
    
         
            +
                    MSG
         
     | 
| 
      
 241 
     | 
    
         
            +
                    load_schema(*args)
         
     | 
| 
       228 
242 
     | 
    
         
             
                  end
         
     | 
| 
       229 
243 
     | 
    
         | 
| 
       230 
     | 
    
         
            -
                  def  
     | 
| 
       231 
     | 
    
         
            -
                     
     | 
| 
       232 
     | 
    
         
            -
             
     | 
| 
      
 244 
     | 
    
         
            +
                  def schema_file(format = ActiveRecord::Base.schema_format)
         
     | 
| 
      
 245 
     | 
    
         
            +
                    case format
         
     | 
| 
      
 246 
     | 
    
         
            +
                    when :ruby
         
     | 
| 
      
 247 
     | 
    
         
            +
                      File.join(db_dir, "schema.rb")
         
     | 
| 
      
 248 
     | 
    
         
            +
                    when :sql
         
     | 
| 
      
 249 
     | 
    
         
            +
                      File.join(db_dir, "structure.sql")
         
     | 
| 
       233 
250 
     | 
    
         
             
                    end
         
     | 
| 
       234 
251 
     | 
    
         
             
                  end
         
     | 
| 
       235 
252 
     | 
    
         | 
| 
       236 
253 
     | 
    
         
             
                  def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
         
     | 
| 
       237 
     | 
    
         
            -
                    each_current_configuration(environment) { |configuration|
         
     | 
| 
       238 
     | 
    
         
            -
                       
     | 
| 
      
 254 
     | 
    
         
            +
                    each_current_configuration(environment) { |configuration, configuration_environment|
         
     | 
| 
      
 255 
     | 
    
         
            +
                      load_schema configuration, format, file, configuration_environment
         
     | 
| 
       239 
256 
     | 
    
         
             
                    }
         
     | 
| 
       240 
257 
     | 
    
         
             
                    ActiveRecord::Base.establish_connection(environment.to_sym)
         
     | 
| 
       241 
258 
     | 
    
         
             
                  end
         
     | 
| 
       242 
259 
     | 
    
         | 
| 
       243 
260 
     | 
    
         
             
                  def check_schema_file(filename)
         
     | 
| 
       244 
261 
     | 
    
         
             
                    unless File.exist?(filename)
         
     | 
| 
       245 
     | 
    
         
            -
                      message = %{#{filename} doesn't exist yet. Run ` 
     | 
| 
       246 
     | 
    
         
            -
                      message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails)
         
     | 
| 
      
 262 
     | 
    
         
            +
                      message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}
         
     | 
| 
      
 263 
     | 
    
         
            +
                      message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails.root)
         
     | 
| 
       247 
264 
     | 
    
         
             
                      Kernel.abort message
         
     | 
| 
       248 
265 
     | 
    
         
             
                    end
         
     | 
| 
       249 
266 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -270,12 +287,12 @@ module ActiveRecord 
     | 
|
| 
       270 
287 
     | 
    
         | 
| 
       271 
288 
     | 
    
         
             
                  def each_current_configuration(environment)
         
     | 
| 
       272 
289 
     | 
    
         
             
                    environments = [environment]
         
     | 
| 
       273 
     | 
    
         
            -
                     
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
      
 290 
     | 
    
         
            +
                    environments << 'test' if environment == 'development'
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
                    ActiveRecord::Base.configurations.slice(*environments).each do |configuration_environment, configuration|
         
     | 
| 
      
 293 
     | 
    
         
            +
                      next unless configuration["database"]
         
     | 
| 
       275 
294 
     | 
    
         | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
                    configurations.compact.each do |configuration|
         
     | 
| 
       278 
     | 
    
         
            -
                      yield configuration unless configuration['database'].blank?
         
     | 
| 
      
 295 
     | 
    
         
            +
                      yield configuration, configuration_environment
         
     | 
| 
       279 
296 
     | 
    
         
             
                    end
         
     | 
| 
       280 
297 
     | 
    
         
             
                  end
         
     | 
| 
       281 
298 
     | 
    
         | 
| 
         @@ -1,8 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Tasks # :nodoc:
         
     | 
| 
       3 
3 
     | 
    
         
             
                class MySQLDatabaseTasks # :nodoc:
         
     | 
| 
       4 
     | 
    
         
            -
                  DEFAULT_CHARSET     = ENV['CHARSET']   || 'utf8'
         
     | 
| 
       5 
     | 
    
         
            -
                  DEFAULT_COLLATION   = ENV['COLLATION'] || 'utf8_unicode_ci'
         
     | 
| 
       6 
4 
     | 
    
         
             
                  ACCESS_DENIED_ERROR = 1045
         
     | 
| 
       7 
5 
     | 
    
         | 
| 
       8 
6 
     | 
    
         
             
                  delegate :connection, :establish_connection, to: ActiveRecord::Base
         
     | 
| 
         @@ -23,7 +21,7 @@ module ActiveRecord 
     | 
|
| 
       23 
21 
     | 
    
         
             
                    end
         
     | 
| 
       24 
22 
     | 
    
         
             
                  rescue error_class => error
         
     | 
| 
       25 
23 
     | 
    
         
             
                    if error.respond_to?(:errno) && error.errno == ACCESS_DENIED_ERROR
         
     | 
| 
       26 
     | 
    
         
            -
                      $stdout.print error. 
     | 
| 
      
 24 
     | 
    
         
            +
                      $stdout.print error.message
         
     | 
| 
       27 
25 
     | 
    
         
             
                      establish_connection root_configuration_without_database
         
     | 
| 
       28 
26 
     | 
    
         
             
                      connection.create_database configuration['database'], creation_options
         
     | 
| 
       29 
27 
     | 
    
         
             
                      if configuration['username'] != 'root'
         
     | 
| 
         @@ -59,6 +57,7 @@ module ActiveRecord 
     | 
|
| 
       59 
57 
     | 
    
         
             
                    args = prepare_command_options
         
     | 
| 
       60 
58 
     | 
    
         
             
                    args.concat(["--result-file", "#{filename}"])
         
     | 
| 
       61 
59 
     | 
    
         
             
                    args.concat(["--no-data"])
         
     | 
| 
      
 60 
     | 
    
         
            +
                    args.concat(["--routines"])
         
     | 
| 
       62 
61 
     | 
    
         
             
                    args.concat(["#{configuration['database']}"])
         
     | 
| 
       63 
62 
     | 
    
         | 
| 
       64 
63 
     | 
    
         
             
                    run_cmd('mysqldump', args, 'dumping')
         
     | 
| 
         @@ -86,12 +85,6 @@ module ActiveRecord 
     | 
|
| 
       86 
85 
     | 
    
         
             
                    Hash.new.tap do |options|
         
     | 
| 
       87 
86 
     | 
    
         
             
                      options[:charset]     = configuration['encoding']   if configuration.include? 'encoding'
         
     | 
| 
       88 
87 
     | 
    
         
             
                      options[:collation]   = configuration['collation']  if configuration.include? 'collation'
         
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
                      # Set default charset only when collation isn't set.
         
     | 
| 
       91 
     | 
    
         
            -
                      options[:charset]   ||= DEFAULT_CHARSET unless options[:collation]
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
                      # Set default collation only when charset is also default.
         
     | 
| 
       94 
     | 
    
         
            -
                      options[:collation] ||= DEFAULT_COLLATION if options[:charset] == DEFAULT_CHARSET
         
     | 
| 
       95 
88 
     | 
    
         
             
                    end
         
     | 
| 
       96 
89 
     | 
    
         
             
                  end
         
     | 
| 
       97 
90 
     | 
    
         | 
| 
         @@ -101,8 +94,6 @@ module ActiveRecord 
     | 
|
| 
       101 
94 
     | 
    
         
             
                      ArJdbcMySQL::Error
         
     | 
| 
       102 
95 
     | 
    
         
             
                    elsif defined?(Mysql2)
         
     | 
| 
       103 
96 
     | 
    
         
             
                      Mysql2::Error
         
     | 
| 
       104 
     | 
    
         
            -
                    elsif defined?(Mysql)
         
     | 
| 
       105 
     | 
    
         
            -
                      Mysql::Error
         
     | 
| 
       106 
97 
     | 
    
         
             
                    else
         
     | 
| 
       107 
98 
     | 
    
         
             
                      StandardError
         
     | 
| 
       108 
99 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -129,7 +120,7 @@ IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION; 
     | 
|
| 
       129 
120 
     | 
    
         
             
                  end
         
     | 
| 
       130 
121 
     | 
    
         | 
| 
       131 
122 
     | 
    
         
             
                  def prepare_command_options
         
     | 
| 
       132 
     | 
    
         
            -
                    {
         
     | 
| 
      
 123 
     | 
    
         
            +
                    args = {
         
     | 
| 
       133 
124 
     | 
    
         
             
                      'host'      => '--host',
         
     | 
| 
       134 
125 
     | 
    
         
             
                      'port'      => '--port',
         
     | 
| 
       135 
126 
     | 
    
         
             
                      'socket'    => '--socket',
         
     | 
| 
         @@ -142,6 +133,8 @@ IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION; 
     | 
|
| 
       142 
133 
     | 
    
         
             
                      'sslcipher' => '--ssl-cipher',
         
     | 
| 
       143 
134 
     | 
    
         
             
                      'sslkey'    => '--ssl-key'
         
     | 
| 
       144 
135 
     | 
    
         
             
                    }.map { |opt, arg| "#{arg}=#{configuration[opt]}" if configuration[opt] }.compact
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                    args
         
     | 
| 
       145 
138 
     | 
    
         
             
                  end
         
     | 
| 
       146 
139 
     | 
    
         | 
| 
       147 
140 
     | 
    
         
             
                  def run_cmd(cmd, args, action)
         
     | 
| 
         @@ -149,8 +142,7 @@ IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION; 
     | 
|
| 
       149 
142 
     | 
    
         
             
                  end
         
     | 
| 
       150 
143 
     | 
    
         | 
| 
       151 
144 
     | 
    
         
             
                  def run_cmd_error(cmd, args, action)
         
     | 
| 
       152 
     | 
    
         
            -
                    msg = "failed to execute 
     | 
| 
       153 
     | 
    
         
            -
                    msg << "#{cmd}"
         
     | 
| 
      
 145 
     | 
    
         
            +
                    msg = "failed to execute: `#{cmd}`\n"
         
     | 
| 
       154 
146 
     | 
    
         
             
                    msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
         
     | 
| 
       155 
147 
     | 
    
         
             
                    msg
         
     | 
| 
       156 
148 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -16,7 +16,7 @@ module ActiveRecord 
     | 
|
| 
       16 
16 
     | 
    
         
             
                      configuration.merge('encoding' => encoding)
         
     | 
| 
       17 
17 
     | 
    
         
             
                    establish_connection configuration
         
     | 
| 
       18 
18 
     | 
    
         
             
                  rescue ActiveRecord::StatementInvalid => error
         
     | 
| 
       19 
     | 
    
         
            -
                    if  
     | 
| 
      
 19 
     | 
    
         
            +
                    if error.cause.is_a?(PG::DuplicateDatabase)
         
     | 
| 
       20 
20 
     | 
    
         
             
                      raise DatabaseAlreadyExists
         
     | 
| 
       21 
21 
     | 
    
         
             
                    else
         
     | 
| 
       22 
22 
     | 
    
         
             
                      raise
         
     | 
| 
         @@ -44,8 +44,17 @@ module ActiveRecord 
     | 
|
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                  def structure_dump(filename)
         
     | 
| 
       46 
46 
     | 
    
         
             
                    set_psql_env
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    search_path = case ActiveRecord::Base.dump_schemas
         
     | 
| 
      
 49 
     | 
    
         
            +
                    when :schema_search_path
         
     | 
| 
      
 50 
     | 
    
         
            +
                      configuration['schema_search_path']
         
     | 
| 
      
 51 
     | 
    
         
            +
                    when :all
         
     | 
| 
      
 52 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 53 
     | 
    
         
            +
                    when String
         
     | 
| 
      
 54 
     | 
    
         
            +
                      ActiveRecord::Base.dump_schemas
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
       47 
57 
     | 
    
         
             
                    args = ['-s', '-x', '-O', '-f', filename]
         
     | 
| 
       48 
     | 
    
         
            -
                    search_path = configuration['schema_search_path']
         
     | 
| 
       49 
58 
     | 
    
         
             
                    unless search_path.blank?
         
     | 
| 
       50 
59 
     | 
    
         
             
                      args += search_path.split(',').map do |part|
         
     | 
| 
       51 
60 
     | 
    
         
             
                        "--schema=#{part.strip}"
         
     | 
| 
         @@ -59,7 +68,7 @@ module ActiveRecord 
     | 
|
| 
       59 
68 
     | 
    
         
             
                  def structure_load(filename)
         
     | 
| 
       60 
69 
     | 
    
         
             
                    set_psql_env
         
     | 
| 
       61 
70 
     | 
    
         
             
                    args = [ '-q', '-f', filename, configuration['database'] ]
         
     | 
| 
       62 
     | 
    
         
            -
                    run_cmd('psql', args, 'loading')
         
     | 
| 
      
 71 
     | 
    
         
            +
                    run_cmd('psql', args, 'loading' )
         
     | 
| 
       63 
72 
     | 
    
         
             
                  end
         
     | 
| 
       64 
73 
     | 
    
         | 
| 
       65 
74 
     | 
    
         
             
                  private
         
     | 
| 
         @@ -19,11 +19,15 @@ module ActiveRecord 
     | 
|
| 
       19 
19 
     | 
    
         
             
                    path = Pathname.new configuration['database']
         
     | 
| 
       20 
20 
     | 
    
         
             
                    file = path.absolute? ? path.to_s : File.join(root, path)
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                    FileUtils.rm(file) 
     | 
| 
      
 22 
     | 
    
         
            +
                    FileUtils.rm(file)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  rescue Errno::ENOENT => error
         
     | 
| 
      
 24 
     | 
    
         
            +
                    raise NoDatabaseError.new(error.message, error)
         
     | 
| 
       23 
25 
     | 
    
         
             
                  end
         
     | 
| 
       24 
26 
     | 
    
         | 
| 
       25 
27 
     | 
    
         
             
                  def purge
         
     | 
| 
       26 
28 
     | 
    
         
             
                    drop
         
     | 
| 
      
 29 
     | 
    
         
            +
                  rescue NoDatabaseError
         
     | 
| 
      
 30 
     | 
    
         
            +
                  ensure
         
     | 
| 
       27 
31 
     | 
    
         
             
                    create
         
     | 
| 
       28 
32 
     | 
    
         
             
                  end
         
     | 
| 
       29 
33 
     | 
    
         | 
| 
         @@ -1,5 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       2 
     | 
    
         
            -
              # = Active Record Timestamp
         
     | 
| 
      
 2 
     | 
    
         
            +
              # = Active Record \Timestamp
         
     | 
| 
       3 
3 
     | 
    
         
             
              #
         
     | 
| 
       4 
4 
     | 
    
         
             
              # Active Record automatically timestamps create and update operations if the
         
     | 
| 
       5 
5 
     | 
    
         
             
              # table has fields named <tt>created_at/created_on</tt> or
         
     | 
| 
         @@ -15,14 +15,25 @@ module ActiveRecord 
     | 
|
| 
       15 
15 
     | 
    
         
             
              #
         
     | 
| 
       16 
16 
     | 
    
         
             
              # == Time Zone aware attributes
         
     | 
| 
       17 
17 
     | 
    
         
             
              #
         
     | 
| 
       18 
     | 
    
         
            -
              #  
     | 
| 
      
 18 
     | 
    
         
            +
              # Active Record keeps all the <tt>datetime</tt> and <tt>time</tt> columns
         
     | 
| 
      
 19 
     | 
    
         
            +
              # timezone aware. By default, these values are stored in the database as UTC
         
     | 
| 
      
 20 
     | 
    
         
            +
              # and converted back to the current <tt>Time.zone</tt> when pulled from the database.
         
     | 
| 
       19 
21 
     | 
    
         
             
              #
         
     | 
| 
       20 
     | 
    
         
            -
              # 
     | 
| 
      
 22 
     | 
    
         
            +
              # This feature can be turned off completely by setting:
         
     | 
| 
       21 
23 
     | 
    
         
             
              #
         
     | 
| 
       22 
     | 
    
         
            -
              #  
     | 
| 
      
 24 
     | 
    
         
            +
              #   config.active_record.time_zone_aware_attributes = false
         
     | 
| 
       23 
25 
     | 
    
         
             
              #
         
     | 
| 
       24 
     | 
    
         
            -
              #  
     | 
| 
       25 
     | 
    
         
            -
              #  
     | 
| 
      
 26 
     | 
    
         
            +
              # You can also specify that only <tt>datetime</tt> columns should be time-zone
         
     | 
| 
      
 27 
     | 
    
         
            +
              # aware (while <tt>time</tt> should not) by setting:
         
     | 
| 
      
 28 
     | 
    
         
            +
              #
         
     | 
| 
      
 29 
     | 
    
         
            +
              #   ActiveRecord::Base.time_zone_aware_types = [:datetime]
         
     | 
| 
      
 30 
     | 
    
         
            +
              #
         
     | 
| 
      
 31 
     | 
    
         
            +
              # You can also add database specific timezone aware types. For example, for PostgreSQL:
         
     | 
| 
      
 32 
     | 
    
         
            +
              #
         
     | 
| 
      
 33 
     | 
    
         
            +
              #   ActiveRecord::Base.time_zone_aware_types += [:tsrange, :tstzrange]
         
     | 
| 
      
 34 
     | 
    
         
            +
              #
         
     | 
| 
      
 35 
     | 
    
         
            +
              # Finally, you can indicate specific attributes of a model for which time zone
         
     | 
| 
      
 36 
     | 
    
         
            +
              # conversion should not applied, for instance by setting:
         
     | 
| 
       26 
37 
     | 
    
         
             
              #
         
     | 
| 
       27 
38 
     | 
    
         
             
              #   class Topic < ActiveRecord::Base
         
     | 
| 
       28 
39 
     | 
    
         
             
              #     self.skip_time_zone_conversion_for_attributes = [:written_on]
         
     | 
| 
         @@ -57,8 +68,8 @@ module ActiveRecord 
     | 
|
| 
       57 
68 
     | 
    
         
             
                  super
         
     | 
| 
       58 
69 
     | 
    
         
             
                end
         
     | 
| 
       59 
70 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                def _update_record(*args)
         
     | 
| 
       61 
     | 
    
         
            -
                  if should_record_timestamps?
         
     | 
| 
      
 71 
     | 
    
         
            +
                def _update_record(*args, touch: true, **options)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  if touch && should_record_timestamps?
         
     | 
| 
       62 
73 
     | 
    
         
             
                    current_time = current_time_from_proper_timezone
         
     | 
| 
       63 
74 
     | 
    
         | 
| 
       64 
75 
     | 
    
         
             
                    timestamp_attributes_for_update_in_model.each do |column|
         
     | 
| 
         @@ -67,7 +78,7 @@ module ActiveRecord 
     | 
|
| 
       67 
78 
     | 
    
         
             
                      write_attribute(column, current_time)
         
     | 
| 
       68 
79 
     | 
    
         
             
                    end
         
     | 
| 
       69 
80 
     | 
    
         
             
                  end
         
     | 
| 
       70 
     | 
    
         
            -
                  super
         
     | 
| 
      
 81 
     | 
    
         
            +
                  super(*args)
         
     | 
| 
       71 
82 
     | 
    
         
             
                end
         
     | 
| 
       72 
83 
     | 
    
         | 
| 
       73 
84 
     | 
    
         
             
                def should_record_timestamps?
         
     | 
| 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ActiveRecord
         
     | 
| 
      
 2 
     | 
    
         
            +
              # = Active Record Touch Later
         
     | 
| 
      
 3 
     | 
    
         
            +
              module TouchLater
         
     | 
| 
      
 4 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                included do
         
     | 
| 
      
 7 
     | 
    
         
            +
                  before_commit_without_transaction_enrollment :touch_deferred_attributes
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def touch_later(*names) # :nodoc:
         
     | 
| 
      
 11 
     | 
    
         
            +
                  unless persisted?
         
     | 
| 
      
 12 
     | 
    
         
            +
                    raise ActiveRecordError, <<-MSG.squish
         
     | 
| 
      
 13 
     | 
    
         
            +
                      cannot touch on a new or destroyed record object. Consider using
         
     | 
| 
      
 14 
     | 
    
         
            +
                      persisted?, new_record?, or destroyed? before touching
         
     | 
| 
      
 15 
     | 
    
         
            +
                    MSG
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  @_defer_touch_attrs ||= timestamp_attributes_for_update_in_model
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @_defer_touch_attrs |= names
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @_touch_time = current_time_from_proper_timezone
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  surreptitiously_touch @_defer_touch_attrs
         
     | 
| 
      
 23 
     | 
    
         
            +
                  self.class.connection.add_transaction_record self
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  # touch the parents as we are not calling the after_save callbacks
         
     | 
| 
      
 26 
     | 
    
         
            +
                  self.class.reflect_on_all_associations(:belongs_to).each do |r|
         
     | 
| 
      
 27 
     | 
    
         
            +
                    if touch = r.options[:touch]
         
     | 
| 
      
 28 
     | 
    
         
            +
                      ActiveRecord::Associations::Builder::BelongsTo.touch_record(self, r.foreign_key, r.name, touch, :touch_later)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def touch(*names, time: nil) # :nodoc:
         
     | 
| 
      
 34 
     | 
    
         
            +
                  if has_defer_touch_attrs?
         
     | 
| 
      
 35 
     | 
    
         
            +
                    names |= @_defer_touch_attrs
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  super(*names, time: time)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                private
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  def surreptitiously_touch(attrs)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    attrs.each { |attr| write_attribute attr, @_touch_time }
         
     | 
| 
      
 44 
     | 
    
         
            +
                    clear_attribute_changes attrs
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def touch_deferred_attributes
         
     | 
| 
      
 48 
     | 
    
         
            +
                    if has_defer_touch_attrs? && persisted?
         
     | 
| 
      
 49 
     | 
    
         
            +
                      touch(*@_defer_touch_attrs, time: @_touch_time)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      @_defer_touch_attrs, @_touch_time = nil, nil
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def has_defer_touch_attrs?
         
     | 
| 
      
 55 
     | 
    
         
            +
                    defined?(@_defer_touch_attrs) && @_defer_touch_attrs.present?
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  def belongs_to_touch_method
         
     | 
| 
      
 59 
     | 
    
         
            +
                    :touch_later
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -4,32 +4,23 @@ module ActiveRecord 
     | 
|
| 
       4 
4 
     | 
    
         
             
                extend ActiveSupport::Concern
         
     | 
| 
       5 
5 
     | 
    
         
             
                #:nodoc:
         
     | 
| 
       6 
6 
     | 
    
         
             
                ACTIONS = [:create, :destroy, :update]
         
     | 
| 
       7 
     | 
    
         
            -
                #:nodoc:
         
     | 
| 
       8 
     | 
    
         
            -
                CALLBACK_WARN_MESSAGE = "Currently, Active Record suppresses errors raised " \
         
     | 
| 
       9 
     | 
    
         
            -
                  "within `after_rollback`/`after_commit` callbacks and only print them to " \
         
     | 
| 
       10 
     | 
    
         
            -
                  "the logs. In the next version, these errors will no longer be suppressed. " \
         
     | 
| 
       11 
     | 
    
         
            -
                  "Instead, the errors will propagate normally just like in other Active " \
         
     | 
| 
       12 
     | 
    
         
            -
                  "Record callbacks.\n" \
         
     | 
| 
       13 
     | 
    
         
            -
                  "\n" \
         
     | 
| 
       14 
     | 
    
         
            -
                  "You can opt into the new behavior and remove this warning by setting:\n" \
         
     | 
| 
       15 
     | 
    
         
            -
                  "\n" \
         
     | 
| 
       16 
     | 
    
         
            -
                  "  config.active_record.raise_in_transactional_callbacks = true\n\n"
         
     | 
| 
       17 
7 
     | 
    
         | 
| 
       18 
8 
     | 
    
         
             
                included do
         
     | 
| 
       19 
9 
     | 
    
         
             
                  define_callbacks :commit, :rollback,
         
     | 
| 
       20 
     | 
    
         
            -
                                    
     | 
| 
      
 10 
     | 
    
         
            +
                                   :before_commit,
         
     | 
| 
      
 11 
     | 
    
         
            +
                                   :before_commit_without_transaction_enrollment,
         
     | 
| 
      
 12 
     | 
    
         
            +
                                   :commit_without_transaction_enrollment,
         
     | 
| 
      
 13 
     | 
    
         
            +
                                   :rollback_without_transaction_enrollment,
         
     | 
| 
      
 14 
     | 
    
         
            +
                                   terminator: deprecated_false_terminator,
         
     | 
| 
       21 
15 
     | 
    
         
             
                                   scope: [:kind, :name]
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                  mattr_accessor :raise_in_transactional_callbacks, instance_writer: false
         
     | 
| 
       24 
     | 
    
         
            -
                  self.raise_in_transactional_callbacks = false
         
     | 
| 
       25 
16 
     | 
    
         
             
                end
         
     | 
| 
       26 
17 
     | 
    
         | 
| 
       27 
18 
     | 
    
         
             
                # = Active Record Transactions
         
     | 
| 
       28 
19 
     | 
    
         
             
                #
         
     | 
| 
       29 
     | 
    
         
            -
                # Transactions are protective blocks where SQL statements are only permanent
         
     | 
| 
      
 20 
     | 
    
         
            +
                # \Transactions are protective blocks where SQL statements are only permanent
         
     | 
| 
       30 
21 
     | 
    
         
             
                # if they can all succeed as one atomic action. The classic example is a
         
     | 
| 
       31 
22 
     | 
    
         
             
                # transfer between two accounts where you can only have a deposit if the
         
     | 
| 
       32 
     | 
    
         
            -
                # withdrawal succeeded and vice versa. Transactions enforce the integrity of
         
     | 
| 
      
 23 
     | 
    
         
            +
                # withdrawal succeeded and vice versa. \Transactions enforce the integrity of
         
     | 
| 
       33 
24 
     | 
    
         
             
                # the database and guard the data against program errors or database
         
     | 
| 
       34 
25 
     | 
    
         
             
                # break-downs. So basically you should use transaction blocks whenever you
         
     | 
| 
       35 
26 
     | 
    
         
             
                # have a number of statements that must be executed together or not at all.
         
     | 
| 
         @@ -49,20 +40,20 @@ module ActiveRecord 
     | 
|
| 
       49 
40 
     | 
    
         
             
                #
         
     | 
| 
       50 
41 
     | 
    
         
             
                # == Different Active Record classes in a single transaction
         
     | 
| 
       51 
42 
     | 
    
         
             
                #
         
     | 
| 
       52 
     | 
    
         
            -
                # Though the transaction class method is called on some Active Record class,
         
     | 
| 
      
 43 
     | 
    
         
            +
                # Though the #transaction class method is called on some Active Record class,
         
     | 
| 
       53 
44 
     | 
    
         
             
                # the objects within the transaction block need not all be instances of
         
     | 
| 
       54 
45 
     | 
    
         
             
                # that class. This is because transactions are per-database connection, not
         
     | 
| 
       55 
46 
     | 
    
         
             
                # per-model.
         
     | 
| 
       56 
47 
     | 
    
         
             
                #
         
     | 
| 
       57 
48 
     | 
    
         
             
                # In this example a +balance+ record is transactionally saved even
         
     | 
| 
       58 
     | 
    
         
            -
                # though  
     | 
| 
      
 49 
     | 
    
         
            +
                # though #transaction is called on the +Account+ class:
         
     | 
| 
       59 
50 
     | 
    
         
             
                #
         
     | 
| 
       60 
51 
     | 
    
         
             
                #   Account.transaction do
         
     | 
| 
       61 
52 
     | 
    
         
             
                #     balance.save!
         
     | 
| 
       62 
53 
     | 
    
         
             
                #     account.save!
         
     | 
| 
       63 
54 
     | 
    
         
             
                #   end
         
     | 
| 
       64 
55 
     | 
    
         
             
                #
         
     | 
| 
       65 
     | 
    
         
            -
                # The  
     | 
| 
      
 56 
     | 
    
         
            +
                # The #transaction method is also available as a model instance method.
         
     | 
| 
       66 
57 
     | 
    
         
             
                # For example, you can also do this:
         
     | 
| 
       67 
58 
     | 
    
         
             
                #
         
     | 
| 
       68 
59 
     | 
    
         
             
                #   balance.transaction do
         
     | 
| 
         @@ -89,7 +80,8 @@ module ActiveRecord 
     | 
|
| 
       89 
80 
     | 
    
         
             
                #
         
     | 
| 
       90 
81 
     | 
    
         
             
                # == +save+ and +destroy+ are automatically wrapped in a transaction
         
     | 
| 
       91 
82 
     | 
    
         
             
                #
         
     | 
| 
       92 
     | 
    
         
            -
                # Both  
     | 
| 
      
 83 
     | 
    
         
            +
                # Both {#save}[rdoc-ref:Persistence#save] and
         
     | 
| 
      
 84 
     | 
    
         
            +
                # {#destroy}[rdoc-ref:Persistence#destroy] come wrapped in a transaction that ensures
         
     | 
| 
       93 
85 
     | 
    
         
             
                # that whatever you do in validations or callbacks will happen under its
         
     | 
| 
       94 
86 
     | 
    
         
             
                # protected cover. So you can use validations to check for values that
         
     | 
| 
       95 
87 
     | 
    
         
             
                # the transaction depends on or you can raise exceptions in the callbacks
         
     | 
| 
         @@ -98,7 +90,7 @@ module ActiveRecord 
     | 
|
| 
       98 
90 
     | 
    
         
             
                # As a consequence changes to the database are not seen outside your connection
         
     | 
| 
       99 
91 
     | 
    
         
             
                # until the operation is complete. For example, if you try to update the index
         
     | 
| 
       100 
92 
     | 
    
         
             
                # of a search engine in +after_save+ the indexer won't see the updated record.
         
     | 
| 
       101 
     | 
    
         
            -
                # The  
     | 
| 
      
 93 
     | 
    
         
            +
                # The #after_commit callback is the only one that is triggered once the update
         
     | 
| 
       102 
94 
     | 
    
         
             
                # is committed. See below.
         
     | 
| 
       103 
95 
     | 
    
         
             
                #
         
     | 
| 
       104 
96 
     | 
    
         
             
                # == Exception handling and rolling back
         
     | 
| 
         @@ -107,11 +99,11 @@ module ActiveRecord 
     | 
|
| 
       107 
99 
     | 
    
         
             
                # be propagated (after triggering the ROLLBACK), so you should be ready to
         
     | 
| 
       108 
100 
     | 
    
         
             
                # catch those in your application code.
         
     | 
| 
       109 
101 
     | 
    
         
             
                #
         
     | 
| 
       110 
     | 
    
         
            -
                # One exception is the  
     | 
| 
      
 102 
     | 
    
         
            +
                # One exception is the ActiveRecord::Rollback exception, which will trigger
         
     | 
| 
       111 
103 
     | 
    
         
             
                # a ROLLBACK when raised, but not be re-raised by the transaction block.
         
     | 
| 
       112 
104 
     | 
    
         
             
                #
         
     | 
| 
       113 
     | 
    
         
            -
                # *Warning*: one should not catch  
     | 
| 
       114 
     | 
    
         
            -
                # inside a transaction block.  
     | 
| 
      
 105 
     | 
    
         
            +
                # *Warning*: one should not catch ActiveRecord::StatementInvalid exceptions
         
     | 
| 
      
 106 
     | 
    
         
            +
                # inside a transaction block. ActiveRecord::StatementInvalid exceptions indicate that an
         
     | 
| 
       115 
107 
     | 
    
         
             
                # error occurred at the database level, for example when a unique constraint
         
     | 
| 
       116 
108 
     | 
    
         
             
                # is violated. On some database systems, such as PostgreSQL, database errors
         
     | 
| 
       117 
109 
     | 
    
         
             
                # inside a transaction cause the entire transaction to become unusable
         
     | 
| 
         @@ -132,16 +124,16 @@ module ActiveRecord 
     | 
|
| 
       132 
124 
     | 
    
         
             
                #     # statement will cause a PostgreSQL error, even though the unique
         
     | 
| 
       133 
125 
     | 
    
         
             
                #     # constraint is no longer violated:
         
     | 
| 
       134 
126 
     | 
    
         
             
                #     Number.create(i: 1)
         
     | 
| 
       135 
     | 
    
         
            -
                #     # => " 
     | 
| 
      
 127 
     | 
    
         
            +
                #     # => "PG::Error: ERROR:  current transaction is aborted, commands
         
     | 
| 
       136 
128 
     | 
    
         
             
                #     #     ignored until end of transaction block"
         
     | 
| 
       137 
129 
     | 
    
         
             
                #   end
         
     | 
| 
       138 
130 
     | 
    
         
             
                #
         
     | 
| 
       139 
131 
     | 
    
         
             
                # One should restart the entire transaction if an
         
     | 
| 
       140 
     | 
    
         
            -
                #  
     | 
| 
      
 132 
     | 
    
         
            +
                # ActiveRecord::StatementInvalid occurred.
         
     | 
| 
       141 
133 
     | 
    
         
             
                #
         
     | 
| 
       142 
134 
     | 
    
         
             
                # == Nested transactions
         
     | 
| 
       143 
135 
     | 
    
         
             
                #
         
     | 
| 
       144 
     | 
    
         
            -
                #  
     | 
| 
      
 136 
     | 
    
         
            +
                # #transaction calls can be nested. By default, this makes all database
         
     | 
| 
       145 
137 
     | 
    
         
             
                # statements in the nested transaction block become part of the parent
         
     | 
| 
       146 
138 
     | 
    
         
             
                # transaction. For example, the following behavior may be surprising:
         
     | 
| 
       147 
139 
     | 
    
         
             
                #
         
     | 
| 
         @@ -153,7 +145,7 @@ module ActiveRecord 
     | 
|
| 
       153 
145 
     | 
    
         
             
                #     end
         
     | 
| 
       154 
146 
     | 
    
         
             
                #   end
         
     | 
| 
       155 
147 
     | 
    
         
             
                #
         
     | 
| 
       156 
     | 
    
         
            -
                # creates both "Kotori" and "Nemu". Reason is the  
     | 
| 
      
 148 
     | 
    
         
            +
                # creates both "Kotori" and "Nemu". Reason is the ActiveRecord::Rollback
         
     | 
| 
       157 
149 
     | 
    
         
             
                # exception in the nested block does not issue a ROLLBACK. Since these exceptions
         
     | 
| 
       158 
150 
     | 
    
         
             
                # are captured in transaction blocks, the parent block does not see it and the
         
     | 
| 
       159 
151 
     | 
    
         
             
                # real transaction is committed.
         
     | 
| 
         @@ -177,22 +169,22 @@ module ActiveRecord 
     | 
|
| 
       177 
169 
     | 
    
         
             
                # writing, the only database that we're aware of that supports true nested
         
     | 
| 
       178 
170 
     | 
    
         
             
                # transactions, is MS-SQL. Because of this, Active Record emulates nested
         
     | 
| 
       179 
171 
     | 
    
         
             
                # transactions by using savepoints on MySQL and PostgreSQL. See
         
     | 
| 
       180 
     | 
    
         
            -
                # http://dev.mysql.com/doc/refman/5. 
     | 
| 
      
 172 
     | 
    
         
            +
                # http://dev.mysql.com/doc/refman/5.7/en/savepoint.html
         
     | 
| 
       181 
173 
     | 
    
         
             
                # for more information about savepoints.
         
     | 
| 
       182 
174 
     | 
    
         
             
                #
         
     | 
| 
       183 
     | 
    
         
            -
                # === Callbacks
         
     | 
| 
      
 175 
     | 
    
         
            +
                # === \Callbacks
         
     | 
| 
       184 
176 
     | 
    
         
             
                #
         
     | 
| 
       185 
177 
     | 
    
         
             
                # There are two types of callbacks associated with committing and rolling back transactions:
         
     | 
| 
       186 
     | 
    
         
            -
                #  
     | 
| 
      
 178 
     | 
    
         
            +
                # #after_commit and #after_rollback.
         
     | 
| 
       187 
179 
     | 
    
         
             
                #
         
     | 
| 
       188 
     | 
    
         
            -
                #  
     | 
| 
       189 
     | 
    
         
            -
                # transaction immediately after the transaction is committed.  
     | 
| 
      
 180 
     | 
    
         
            +
                # #after_commit callbacks are called on every record saved or destroyed within a
         
     | 
| 
      
 181 
     | 
    
         
            +
                # transaction immediately after the transaction is committed. #after_rollback callbacks
         
     | 
| 
       190 
182 
     | 
    
         
             
                # are called on every record saved or destroyed within a transaction immediately after the
         
     | 
| 
       191 
183 
     | 
    
         
             
                # transaction or savepoint is rolled back.
         
     | 
| 
       192 
184 
     | 
    
         
             
                #
         
     | 
| 
       193 
185 
     | 
    
         
             
                # These callbacks are useful for interacting with other systems since you will be guaranteed
         
     | 
| 
       194 
186 
     | 
    
         
             
                # that the callback is only executed when the database is in a permanent state. For example,
         
     | 
| 
       195 
     | 
    
         
            -
                #  
     | 
| 
      
 187 
     | 
    
         
            +
                # #after_commit is a good spot to put in a hook to clearing a cache since clearing it from
         
     | 
| 
       196 
188 
     | 
    
         
             
                # within a transaction could trigger the cache to be regenerated before the database is updated.
         
     | 
| 
       197 
189 
     | 
    
         
             
                #
         
     | 
| 
       198 
190 
     | 
    
         
             
                # === Caveats
         
     | 
| 
         @@ -206,20 +198,24 @@ module ActiveRecord 
     | 
|
| 
       206 
198 
     | 
    
         
             
                # automatically released. The following example demonstrates the problem:
         
     | 
| 
       207 
199 
     | 
    
         
             
                #
         
     | 
| 
       208 
200 
     | 
    
         
             
                #   Model.connection.transaction do                           # BEGIN
         
     | 
| 
       209 
     | 
    
         
            -
                #     Model.connection.transaction(requires_new: true) do 
     | 
| 
      
 201 
     | 
    
         
            +
                #     Model.connection.transaction(requires_new: true) do     # CREATE SAVEPOINT active_record_1
         
     | 
| 
       210 
202 
     | 
    
         
             
                #       Model.connection.create_table(...)                    # active_record_1 now automatically released
         
     | 
| 
       211 
     | 
    
         
            -
                #     end                                                     # RELEASE  
     | 
| 
      
 203 
     | 
    
         
            +
                #     end                                                     # RELEASE SAVEPOINT active_record_1
         
     | 
| 
       212 
204 
     | 
    
         
             
                #                                                             # ^^^^ BOOM! database error!
         
     | 
| 
       213 
205 
     | 
    
         
             
                #   end
         
     | 
| 
       214 
206 
     | 
    
         
             
                #
         
     | 
| 
       215 
207 
     | 
    
         
             
                # Note that "TRUNCATE" is also a MySQL DDL statement!
         
     | 
| 
       216 
208 
     | 
    
         
             
                module ClassMethods
         
     | 
| 
       217 
     | 
    
         
            -
                  # See  
     | 
| 
      
 209 
     | 
    
         
            +
                  # See the ConnectionAdapters::DatabaseStatements#transaction API docs.
         
     | 
| 
       218 
210 
     | 
    
         
             
                  def transaction(options = {}, &block)
         
     | 
| 
       219 
     | 
    
         
            -
                    # See the ConnectionAdapters::DatabaseStatements#transaction API docs.
         
     | 
| 
       220 
211 
     | 
    
         
             
                    connection.transaction(options, &block)
         
     | 
| 
       221 
212 
     | 
    
         
             
                  end
         
     | 
| 
       222 
213 
     | 
    
         | 
| 
      
 214 
     | 
    
         
            +
                  def before_commit(*args, &block) # :nodoc:
         
     | 
| 
      
 215 
     | 
    
         
            +
                    set_options_for_callbacks!(args)
         
     | 
| 
      
 216 
     | 
    
         
            +
                    set_callback(:before_commit, :before, *args, &block)
         
     | 
| 
      
 217 
     | 
    
         
            +
                  end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
       223 
219 
     | 
    
         
             
                  # This callback is called after a record has been created, updated, or destroyed.
         
     | 
| 
       224 
220 
     | 
    
         
             
                  #
         
     | 
| 
       225 
221 
     | 
    
         
             
                  # You can specify that the callback should only be fired by a certain action with
         
     | 
| 
         @@ -232,32 +228,69 @@ module ActiveRecord 
     | 
|
| 
       232 
228 
     | 
    
         
             
                  #   after_commit :do_foo_bar, on: [:create, :update]
         
     | 
| 
       233 
229 
     | 
    
         
             
                  #   after_commit :do_bar_baz, on: [:update, :destroy]
         
     | 
| 
       234 
230 
     | 
    
         
             
                  #
         
     | 
| 
       235 
     | 
    
         
            -
                  # Note that transactional fixtures do not play well with this feature. Please
         
     | 
| 
       236 
     | 
    
         
            -
                  # use the +test_after_commit+ gem to have these hooks fired in tests.
         
     | 
| 
       237 
231 
     | 
    
         
             
                  def after_commit(*args, &block)
         
     | 
| 
       238 
232 
     | 
    
         
             
                    set_options_for_callbacks!(args)
         
     | 
| 
       239 
233 
     | 
    
         
             
                    set_callback(:commit, :after, *args, &block)
         
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
      
 234 
     | 
    
         
            +
                  end
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
                  # Shortcut for <tt>after_commit :hook, on: :create</tt>.
         
     | 
| 
      
 237 
     | 
    
         
            +
                  def after_create_commit(*args, &block)
         
     | 
| 
      
 238 
     | 
    
         
            +
                    set_options_for_callbacks!(args, on: :create)
         
     | 
| 
      
 239 
     | 
    
         
            +
                    set_callback(:commit, :after, *args, &block)
         
     | 
| 
      
 240 
     | 
    
         
            +
                  end
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                  # Shortcut for <tt>after_commit :hook, on: :update</tt>.
         
     | 
| 
      
 243 
     | 
    
         
            +
                  def after_update_commit(*args, &block)
         
     | 
| 
      
 244 
     | 
    
         
            +
                    set_options_for_callbacks!(args, on: :update)
         
     | 
| 
      
 245 
     | 
    
         
            +
                    set_callback(:commit, :after, *args, &block)
         
     | 
| 
      
 246 
     | 
    
         
            +
                  end
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
                  # Shortcut for <tt>after_commit :hook, on: :destroy</tt>.
         
     | 
| 
      
 249 
     | 
    
         
            +
                  def after_destroy_commit(*args, &block)
         
     | 
| 
      
 250 
     | 
    
         
            +
                    set_options_for_callbacks!(args, on: :destroy)
         
     | 
| 
      
 251 
     | 
    
         
            +
                    set_callback(:commit, :after, *args, &block)
         
     | 
| 
       243 
252 
     | 
    
         
             
                  end
         
     | 
| 
       244 
253 
     | 
    
         | 
| 
       245 
254 
     | 
    
         
             
                  # This callback is called after a create, update, or destroy are rolled back.
         
     | 
| 
       246 
255 
     | 
    
         
             
                  #
         
     | 
| 
       247 
     | 
    
         
            -
                  # Please check the documentation of  
     | 
| 
      
 256 
     | 
    
         
            +
                  # Please check the documentation of #after_commit for options.
         
     | 
| 
       248 
257 
     | 
    
         
             
                  def after_rollback(*args, &block)
         
     | 
| 
       249 
258 
     | 
    
         
             
                    set_options_for_callbacks!(args)
         
     | 
| 
       250 
259 
     | 
    
         
             
                    set_callback(:rollback, :after, *args, &block)
         
     | 
| 
       251 
     | 
    
         
            -
             
     | 
| 
       252 
     | 
    
         
            -
             
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
      
 260 
     | 
    
         
            +
                  end
         
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
                  def before_commit_without_transaction_enrollment(*args, &block) # :nodoc:
         
     | 
| 
      
 263 
     | 
    
         
            +
                    set_options_for_callbacks!(args)
         
     | 
| 
      
 264 
     | 
    
         
            +
                    set_callback(:before_commit_without_transaction_enrollment, :before, *args, &block)
         
     | 
| 
      
 265 
     | 
    
         
            +
                  end
         
     | 
| 
      
 266 
     | 
    
         
            +
             
     | 
| 
      
 267 
     | 
    
         
            +
                  def after_commit_without_transaction_enrollment(*args, &block) # :nodoc:
         
     | 
| 
      
 268 
     | 
    
         
            +
                    set_options_for_callbacks!(args)
         
     | 
| 
      
 269 
     | 
    
         
            +
                    set_callback(:commit_without_transaction_enrollment, :after, *args, &block)
         
     | 
| 
      
 270 
     | 
    
         
            +
                  end
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
                  def after_rollback_without_transaction_enrollment(*args, &block) # :nodoc:
         
     | 
| 
      
 273 
     | 
    
         
            +
                    set_options_for_callbacks!(args)
         
     | 
| 
      
 274 
     | 
    
         
            +
                    set_callback(:rollback_without_transaction_enrollment, :after, *args, &block)
         
     | 
| 
      
 275 
     | 
    
         
            +
                  end
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
                  def raise_in_transactional_callbacks
         
     | 
| 
      
 278 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn('ActiveRecord::Base.raise_in_transactional_callbacks is deprecated and will be removed without replacement.')
         
     | 
| 
      
 279 
     | 
    
         
            +
                    true
         
     | 
| 
      
 280 
     | 
    
         
            +
                  end
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                  def raise_in_transactional_callbacks=(value)
         
     | 
| 
      
 283 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn('ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement.')
         
     | 
| 
      
 284 
     | 
    
         
            +
                    value
         
     | 
| 
       254 
285 
     | 
    
         
             
                  end
         
     | 
| 
       255 
286 
     | 
    
         | 
| 
       256 
287 
     | 
    
         
             
                  private
         
     | 
| 
       257 
288 
     | 
    
         | 
| 
       258 
     | 
    
         
            -
                  def set_options_for_callbacks!(args)
         
     | 
| 
       259 
     | 
    
         
            -
                    options = args. 
     | 
| 
       260 
     | 
    
         
            -
                     
     | 
| 
      
 289 
     | 
    
         
            +
                  def set_options_for_callbacks!(args, enforced_options = {})
         
     | 
| 
      
 290 
     | 
    
         
            +
                    options = args.extract_options!.merge!(enforced_options)
         
     | 
| 
      
 291 
     | 
    
         
            +
                    args << options
         
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
                    if options[:on]
         
     | 
| 
       261 
294 
     | 
    
         
             
                      fire_on = Array(options[:on])
         
     | 
| 
       262 
295 
     | 
    
         
             
                      assert_valid_transaction_action(fire_on)
         
     | 
| 
       263 
296 
     | 
    
         
             
                      options[:if] = Array(options[:if])
         
     | 
| 
         @@ -306,26 +339,37 @@ module ActiveRecord 
     | 
|
| 
       306 
339 
     | 
    
         
             
                  clear_transaction_record_state
         
     | 
| 
       307 
340 
     | 
    
         
             
                end
         
     | 
| 
       308 
341 
     | 
    
         | 
| 
       309 
     | 
    
         
            -
                 
     | 
| 
      
 342 
     | 
    
         
            +
                def before_committed! # :nodoc:
         
     | 
| 
      
 343 
     | 
    
         
            +
                  _run_before_commit_without_transaction_enrollment_callbacks
         
     | 
| 
      
 344 
     | 
    
         
            +
                  _run_before_commit_callbacks
         
     | 
| 
      
 345 
     | 
    
         
            +
                end
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
      
 347 
     | 
    
         
            +
                # Call the #after_commit callbacks.
         
     | 
| 
       310 
348 
     | 
    
         
             
                #
         
     | 
| 
       311 
349 
     | 
    
         
             
                # Ensure that it is not called if the object was never persisted (failed create),
         
     | 
| 
       312 
350 
     | 
    
         
             
                # but call it after the commit of a destroyed object.
         
     | 
| 
       313 
     | 
    
         
            -
                def committed!(should_run_callbacks  
     | 
| 
       314 
     | 
    
         
            -
                   
     | 
| 
      
 351 
     | 
    
         
            +
                def committed!(should_run_callbacks: true) #:nodoc:
         
     | 
| 
      
 352 
     | 
    
         
            +
                  if should_run_callbacks && destroyed? || persisted?
         
     | 
| 
      
 353 
     | 
    
         
            +
                    _run_commit_without_transaction_enrollment_callbacks
         
     | 
| 
      
 354 
     | 
    
         
            +
                    _run_commit_callbacks
         
     | 
| 
      
 355 
     | 
    
         
            +
                  end
         
     | 
| 
       315 
356 
     | 
    
         
             
                ensure
         
     | 
| 
       316 
357 
     | 
    
         
             
                  force_clear_transaction_record_state
         
     | 
| 
       317 
358 
     | 
    
         
             
                end
         
     | 
| 
       318 
359 
     | 
    
         | 
| 
       319 
     | 
    
         
            -
                # Call the  
     | 
| 
      
 360 
     | 
    
         
            +
                # Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
         
     | 
| 
       320 
361 
     | 
    
         
             
                # state should be rolled back to the beginning or just to the last savepoint.
         
     | 
| 
       321 
     | 
    
         
            -
                def rolledback!(force_restore_state  
     | 
| 
       322 
     | 
    
         
            -
                   
     | 
| 
      
 362 
     | 
    
         
            +
                def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
         
     | 
| 
      
 363 
     | 
    
         
            +
                  if should_run_callbacks
         
     | 
| 
      
 364 
     | 
    
         
            +
                    _run_rollback_callbacks
         
     | 
| 
      
 365 
     | 
    
         
            +
                    _run_rollback_without_transaction_enrollment_callbacks
         
     | 
| 
      
 366 
     | 
    
         
            +
                  end
         
     | 
| 
       323 
367 
     | 
    
         
             
                ensure
         
     | 
| 
       324 
368 
     | 
    
         
             
                  restore_transaction_record_state(force_restore_state)
         
     | 
| 
       325 
369 
     | 
    
         
             
                  clear_transaction_record_state
         
     | 
| 
       326 
370 
     | 
    
         
             
                end
         
     | 
| 
       327 
371 
     | 
    
         | 
| 
       328 
     | 
    
         
            -
                # Add the record to the current transaction so that the  
     | 
| 
      
 372 
     | 
    
         
            +
                # Add the record to the current transaction so that the #after_rollback and #after_commit callbacks
         
     | 
| 
       329 
373 
     | 
    
         
             
                # can be called.
         
     | 
| 
       330 
374 
     | 
    
         
             
                def add_to_transaction
         
     | 
| 
       331 
375 
     | 
    
         
             
                  if has_transactional_callbacks?
         
     | 
| 
         @@ -423,5 +467,43 @@ module ActiveRecord 
     | 
|
| 
       423 
467 
     | 
    
         
             
                    end
         
     | 
| 
       424 
468 
     | 
    
         
             
                  end
         
     | 
| 
       425 
469 
     | 
    
         
             
                end
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
      
 471 
     | 
    
         
            +
                private
         
     | 
| 
      
 472 
     | 
    
         
            +
             
     | 
| 
      
 473 
     | 
    
         
            +
                def set_transaction_state(state) # :nodoc:
         
     | 
| 
      
 474 
     | 
    
         
            +
                  @transaction_state = state
         
     | 
| 
      
 475 
     | 
    
         
            +
                end
         
     | 
| 
      
 476 
     | 
    
         
            +
             
     | 
| 
      
 477 
     | 
    
         
            +
                def has_transactional_callbacks? # :nodoc:
         
     | 
| 
      
 478 
     | 
    
         
            +
                  !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
         
     | 
| 
      
 479 
     | 
    
         
            +
                end
         
     | 
| 
      
 480 
     | 
    
         
            +
             
     | 
| 
      
 481 
     | 
    
         
            +
                # Updates the attributes on this particular Active Record object so that
         
     | 
| 
      
 482 
     | 
    
         
            +
                # if it's associated with a transaction, then the state of the Active Record
         
     | 
| 
      
 483 
     | 
    
         
            +
                # object will be updated to reflect the current state of the transaction
         
     | 
| 
      
 484 
     | 
    
         
            +
                #
         
     | 
| 
      
 485 
     | 
    
         
            +
                # The +@transaction_state+ variable stores the states of the associated
         
     | 
| 
      
 486 
     | 
    
         
            +
                # transaction. This relies on the fact that a transaction can only be in
         
     | 
| 
      
 487 
     | 
    
         
            +
                # one rollback or commit (otherwise a list of states would be required)
         
     | 
| 
      
 488 
     | 
    
         
            +
                # Each Active Record object inside of a transaction carries that transaction's
         
     | 
| 
      
 489 
     | 
    
         
            +
                # TransactionState.
         
     | 
| 
      
 490 
     | 
    
         
            +
                #
         
     | 
| 
      
 491 
     | 
    
         
            +
                # This method checks to see if the ActiveRecord object's state reflects
         
     | 
| 
      
 492 
     | 
    
         
            +
                # the TransactionState, and rolls back or commits the Active Record object
         
     | 
| 
      
 493 
     | 
    
         
            +
                # as appropriate.
         
     | 
| 
      
 494 
     | 
    
         
            +
                #
         
     | 
| 
      
 495 
     | 
    
         
            +
                # Since Active Record objects can be inside multiple transactions, this
         
     | 
| 
      
 496 
     | 
    
         
            +
                # method recursively goes through the parent of the TransactionState and
         
     | 
| 
      
 497 
     | 
    
         
            +
                # checks if the Active Record object reflects the state of the object.
         
     | 
| 
      
 498 
     | 
    
         
            +
                def sync_with_transaction_state
         
     | 
| 
      
 499 
     | 
    
         
            +
                  update_attributes_from_transaction_state(@transaction_state)
         
     | 
| 
      
 500 
     | 
    
         
            +
                end
         
     | 
| 
      
 501 
     | 
    
         
            +
             
     | 
| 
      
 502 
     | 
    
         
            +
                def update_attributes_from_transaction_state(transaction_state)
         
     | 
| 
      
 503 
     | 
    
         
            +
                  if transaction_state && transaction_state.finalized?
         
     | 
| 
      
 504 
     | 
    
         
            +
                    restore_transaction_record_state if transaction_state.rolledback?
         
     | 
| 
      
 505 
     | 
    
         
            +
                    clear_transaction_record_state
         
     | 
| 
      
 506 
     | 
    
         
            +
                  end
         
     | 
| 
      
 507 
     | 
    
         
            +
                end
         
     | 
| 
       426 
508 
     | 
    
         
             
              end
         
     | 
| 
       427 
509 
     | 
    
         
             
            end
         
     |