activerecord 6.1.6 → 7.1.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 +1627 -983
 - data/MIT-LICENSE +1 -1
 - data/README.rdoc +18 -18
 - data/lib/active_record/aggregations.rb +17 -14
 - data/lib/active_record/association_relation.rb +1 -11
 - data/lib/active_record/associations/association.rb +50 -19
 - data/lib/active_record/associations/association_scope.rb +17 -12
 - data/lib/active_record/associations/belongs_to_association.rb +28 -9
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
 - data/lib/active_record/associations/builder/association.rb +11 -5
 - data/lib/active_record/associations/builder/belongs_to.rb +40 -14
 - data/lib/active_record/associations/builder/collection_association.rb +10 -3
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
 - data/lib/active_record/associations/builder/has_many.rb +3 -2
 - data/lib/active_record/associations/builder/has_one.rb +2 -1
 - data/lib/active_record/associations/builder/singular_association.rb +6 -2
 - data/lib/active_record/associations/collection_association.rb +35 -31
 - data/lib/active_record/associations/collection_proxy.rb +30 -15
 - data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
 - data/lib/active_record/associations/foreign_association.rb +10 -3
 - data/lib/active_record/associations/has_many_association.rb +28 -18
 - data/lib/active_record/associations/has_many_through_association.rb +12 -7
 - data/lib/active_record/associations/has_one_association.rb +20 -10
 - data/lib/active_record/associations/has_one_through_association.rb +1 -1
 - data/lib/active_record/associations/join_dependency.rb +26 -16
 - data/lib/active_record/associations/preloader/association.rb +207 -52
 - data/lib/active_record/associations/preloader/batch.rb +48 -0
 - data/lib/active_record/associations/preloader/branch.rb +147 -0
 - data/lib/active_record/associations/preloader/through_association.rb +50 -14
 - data/lib/active_record/associations/preloader.rb +50 -121
 - data/lib/active_record/associations/singular_association.rb +9 -3
 - data/lib/active_record/associations/through_association.rb +25 -14
 - data/lib/active_record/associations.rb +439 -305
 - data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
 - data/lib/active_record/attribute_assignment.rb +1 -3
 - data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
 - data/lib/active_record/attribute_methods/dirty.rb +73 -22
 - data/lib/active_record/attribute_methods/primary_key.rb +78 -26
 - data/lib/active_record/attribute_methods/query.rb +31 -19
 - data/lib/active_record/attribute_methods/read.rb +25 -10
 - data/lib/active_record/attribute_methods/serialization.rb +194 -37
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
 - data/lib/active_record/attribute_methods/write.rb +10 -13
 - data/lib/active_record/attribute_methods.rb +121 -40
 - data/lib/active_record/attributes.rb +27 -38
 - data/lib/active_record/autosave_association.rb +61 -30
 - data/lib/active_record/base.rb +25 -2
 - data/lib/active_record/callbacks.rb +18 -34
 - data/lib/active_record/coders/column_serializer.rb +61 -0
 - data/lib/active_record/coders/json.rb +1 -1
 - data/lib/active_record/coders/yaml_column.rb +70 -34
 - data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +96 -590
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +172 -50
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +77 -27
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +360 -138
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +631 -149
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +285 -156
 - data/lib/active_record/connection_adapters/column.rb +13 -0
 - data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
 - data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
 - data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +104 -53
 - data/lib/active_record/connection_adapters/pool_config.rb +20 -11
 - data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
 - data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +89 -52
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
 - data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +394 -74
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +509 -247
 - data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
 - data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
 - data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +72 -53
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
 - data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
 - data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +294 -102
 - data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
 - data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
 - data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
 - data/lib/active_record/connection_adapters.rb +9 -6
 - data/lib/active_record/connection_handling.rb +107 -136
 - data/lib/active_record/core.rb +202 -223
 - data/lib/active_record/counter_cache.rb +46 -25
 - data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
 - data/lib/active_record/database_configurations/database_config.rb +21 -12
 - data/lib/active_record/database_configurations/hash_config.rb +84 -16
 - data/lib/active_record/database_configurations/url_config.rb +18 -12
 - data/lib/active_record/database_configurations.rb +95 -59
 - data/lib/active_record/delegated_type.rb +61 -15
 - data/lib/active_record/deprecator.rb +7 -0
 - data/lib/active_record/destroy_association_async_job.rb +3 -1
 - data/lib/active_record/disable_joins_association_relation.rb +39 -0
 - data/lib/active_record/dynamic_matchers.rb +1 -1
 - data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
 - data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
 - data/lib/active_record/encryption/cipher.rb +53 -0
 - data/lib/active_record/encryption/config.rb +68 -0
 - data/lib/active_record/encryption/configurable.rb +60 -0
 - data/lib/active_record/encryption/context.rb +42 -0
 - data/lib/active_record/encryption/contexts.rb +76 -0
 - data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
 - data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
 - data/lib/active_record/encryption/encryptable_record.rb +224 -0
 - data/lib/active_record/encryption/encrypted_attribute_type.rb +151 -0
 - data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
 - data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
 - data/lib/active_record/encryption/encryptor.rb +155 -0
 - data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
 - data/lib/active_record/encryption/errors.rb +15 -0
 - data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
 - data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
 - data/lib/active_record/encryption/key.rb +28 -0
 - data/lib/active_record/encryption/key_generator.rb +53 -0
 - data/lib/active_record/encryption/key_provider.rb +46 -0
 - data/lib/active_record/encryption/message.rb +33 -0
 - data/lib/active_record/encryption/message_serializer.rb +92 -0
 - data/lib/active_record/encryption/null_encryptor.rb +21 -0
 - data/lib/active_record/encryption/properties.rb +76 -0
 - data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
 - data/lib/active_record/encryption/scheme.rb +96 -0
 - data/lib/active_record/encryption.rb +56 -0
 - data/lib/active_record/enum.rb +154 -63
 - data/lib/active_record/errors.rb +171 -15
 - data/lib/active_record/explain.rb +23 -3
 - data/lib/active_record/explain_registry.rb +11 -6
 - data/lib/active_record/explain_subscriber.rb +1 -1
 - data/lib/active_record/fixture_set/file.rb +15 -1
 - data/lib/active_record/fixture_set/model_metadata.rb +14 -4
 - data/lib/active_record/fixture_set/render_context.rb +2 -0
 - data/lib/active_record/fixture_set/table_row.rb +70 -14
 - data/lib/active_record/fixture_set/table_rows.rb +4 -4
 - data/lib/active_record/fixtures.rb +131 -86
 - data/lib/active_record/future_result.rb +164 -0
 - data/lib/active_record/gem_version.rb +3 -3
 - data/lib/active_record/inheritance.rb +81 -29
 - data/lib/active_record/insert_all.rb +135 -22
 - data/lib/active_record/integration.rb +11 -10
 - data/lib/active_record/internal_metadata.rb +119 -33
 - data/lib/active_record/legacy_yaml_adapter.rb +2 -39
 - data/lib/active_record/locking/optimistic.rb +36 -21
 - data/lib/active_record/locking/pessimistic.rb +15 -6
 - data/lib/active_record/log_subscriber.rb +52 -19
 - data/lib/active_record/marshalling.rb +56 -0
 - data/lib/active_record/message_pack.rb +124 -0
 - data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
 - data/lib/active_record/middleware/database_selector.rb +23 -13
 - data/lib/active_record/middleware/shard_selector.rb +62 -0
 - data/lib/active_record/migration/command_recorder.rb +112 -14
 - data/lib/active_record/migration/compatibility.rb +221 -48
 - data/lib/active_record/migration/default_strategy.rb +23 -0
 - data/lib/active_record/migration/execution_strategy.rb +19 -0
 - data/lib/active_record/migration/join_table.rb +1 -1
 - data/lib/active_record/migration/pending_migration_connection.rb +21 -0
 - data/lib/active_record/migration.rb +358 -171
 - data/lib/active_record/model_schema.rb +120 -101
 - data/lib/active_record/nested_attributes.rb +37 -18
 - data/lib/active_record/no_touching.rb +3 -3
 - data/lib/active_record/normalization.rb +167 -0
 - data/lib/active_record/persistence.rb +405 -85
 - data/lib/active_record/promise.rb +84 -0
 - data/lib/active_record/query_cache.rb +3 -21
 - data/lib/active_record/query_logs.rb +174 -0
 - data/lib/active_record/query_logs_formatter.rb +41 -0
 - data/lib/active_record/querying.rb +29 -6
 - data/lib/active_record/railtie.rb +219 -43
 - data/lib/active_record/railties/controller_runtime.rb +13 -9
 - data/lib/active_record/railties/databases.rake +188 -252
 - data/lib/active_record/railties/job_runtime.rb +23 -0
 - data/lib/active_record/readonly_attributes.rb +41 -3
 - data/lib/active_record/reflection.rb +241 -80
 - data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
 - data/lib/active_record/relation/batches.rb +192 -63
 - data/lib/active_record/relation/calculations.rb +219 -90
 - data/lib/active_record/relation/delegation.rb +27 -13
 - data/lib/active_record/relation/finder_methods.rb +108 -51
 - data/lib/active_record/relation/merger.rb +22 -13
 - data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
 - data/lib/active_record/relation/predicate_builder.rb +27 -20
 - data/lib/active_record/relation/query_attribute.rb +30 -12
 - data/lib/active_record/relation/query_methods.rb +654 -127
 - data/lib/active_record/relation/record_fetch_warning.rb +7 -9
 - data/lib/active_record/relation/spawn_methods.rb +20 -3
 - data/lib/active_record/relation/where_clause.rb +10 -19
 - data/lib/active_record/relation.rb +262 -120
 - data/lib/active_record/result.rb +37 -11
 - data/lib/active_record/runtime_registry.rb +18 -13
 - data/lib/active_record/sanitization.rb +65 -20
 - data/lib/active_record/schema.rb +36 -22
 - data/lib/active_record/schema_dumper.rb +73 -24
 - data/lib/active_record/schema_migration.rb +68 -33
 - data/lib/active_record/scoping/default.rb +72 -15
 - data/lib/active_record/scoping/named.rb +5 -13
 - data/lib/active_record/scoping.rb +65 -34
 - data/lib/active_record/secure_password.rb +60 -0
 - data/lib/active_record/secure_token.rb +21 -3
 - data/lib/active_record/serialization.rb +6 -1
 - data/lib/active_record/signed_id.rb +10 -8
 - data/lib/active_record/store.rb +16 -11
 - data/lib/active_record/suppressor.rb +13 -15
 - data/lib/active_record/table_metadata.rb +16 -3
 - data/lib/active_record/tasks/database_tasks.rb +225 -136
 - data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
 - data/lib/active_record/test_databases.rb +1 -1
 - data/lib/active_record/test_fixtures.rb +123 -99
 - data/lib/active_record/timestamp.rb +29 -18
 - data/lib/active_record/token_for.rb +113 -0
 - data/lib/active_record/touch_later.rb +11 -6
 - data/lib/active_record/transactions.rb +48 -27
 - data/lib/active_record/translation.rb +3 -3
 - data/lib/active_record/type/adapter_specific_registry.rb +32 -14
 - data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
 - data/lib/active_record/type/internal/timezone.rb +7 -2
 - data/lib/active_record/type/serialized.rb +9 -5
 - data/lib/active_record/type/time.rb +4 -0
 - data/lib/active_record/type/type_map.rb +17 -20
 - data/lib/active_record/type.rb +1 -2
 - data/lib/active_record/validations/absence.rb +1 -1
 - data/lib/active_record/validations/associated.rb +4 -4
 - data/lib/active_record/validations/numericality.rb +5 -4
 - data/lib/active_record/validations/presence.rb +5 -28
 - data/lib/active_record/validations/uniqueness.rb +51 -6
 - data/lib/active_record/validations.rb +8 -4
 - data/lib/active_record/version.rb +1 -1
 - data/lib/active_record.rb +335 -32
 - data/lib/arel/attributes/attribute.rb +0 -8
 - data/lib/arel/crud.rb +28 -22
 - data/lib/arel/delete_manager.rb +18 -4
 - data/lib/arel/errors.rb +10 -0
 - data/lib/arel/factory_methods.rb +4 -0
 - data/lib/arel/filter_predications.rb +9 -0
 - data/lib/arel/insert_manager.rb +2 -3
 - data/lib/arel/nodes/and.rb +4 -0
 - data/lib/arel/nodes/binary.rb +6 -1
 - data/lib/arel/nodes/bound_sql_literal.rb +61 -0
 - data/lib/arel/nodes/casted.rb +1 -1
 - data/lib/arel/nodes/cte.rb +36 -0
 - data/lib/arel/nodes/delete_statement.rb +12 -13
 - data/lib/arel/nodes/filter.rb +10 -0
 - data/lib/arel/nodes/fragments.rb +35 -0
 - data/lib/arel/nodes/function.rb +1 -0
 - data/lib/arel/nodes/homogeneous_in.rb +1 -9
 - data/lib/arel/nodes/insert_statement.rb +2 -2
 - data/lib/arel/nodes/leading_join.rb +8 -0
 - data/lib/arel/nodes/node.rb +111 -2
 - data/lib/arel/nodes/select_core.rb +2 -2
 - data/lib/arel/nodes/select_statement.rb +2 -2
 - data/lib/arel/nodes/sql_literal.rb +6 -0
 - data/lib/arel/nodes/table_alias.rb +4 -0
 - data/lib/arel/nodes/update_statement.rb +8 -3
 - data/lib/arel/nodes.rb +5 -0
 - data/lib/arel/predications.rb +13 -3
 - data/lib/arel/select_manager.rb +10 -4
 - data/lib/arel/table.rb +9 -6
 - data/lib/arel/tree_manager.rb +0 -12
 - data/lib/arel/update_manager.rb +18 -4
 - data/lib/arel/visitors/dot.rb +80 -90
 - data/lib/arel/visitors/mysql.rb +16 -3
 - data/lib/arel/visitors/postgresql.rb +0 -10
 - data/lib/arel/visitors/to_sql.rb +139 -19
 - data/lib/arel/visitors/visitor.rb +2 -2
 - data/lib/arel.rb +18 -3
 - data/lib/rails/generators/active_record/application_record/USAGE +8 -0
 - data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
 - data/lib/rails/generators/active_record/migration.rb +3 -1
 - data/lib/rails/generators/active_record/model/USAGE +113 -0
 - data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
 - data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
 - data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
 - data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
 - data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
 - data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
 - metadata +93 -13
 - data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
 - data/lib/active_record/null_relation.rb +0 -67
 
    
        data/MIT-LICENSE
    CHANGED
    
    
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            = Active Record -- Object-relational mapping in Rails
         
     | 
| 
      
 1 
     | 
    
         
            +
            = Active Record -- Object-relational mapping in \Rails
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            Active Record connects classes to relational database tables to establish an
         
     | 
| 
       4 
4 
     | 
    
         
             
            almost zero-configuration persistence layer for applications. The library
         
     | 
| 
         @@ -13,29 +13,28 @@ columns. Although these mappings can be defined explicitly, it's recommended 
     | 
|
| 
       13 
13 
     | 
    
         
             
            to follow naming conventions, especially when getting started with the
         
     | 
| 
       14 
14 
     | 
    
         
             
            library.
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
            You can read more about Active Record in the {Active Record Basics}[https:// 
     | 
| 
      
 16 
     | 
    
         
            +
            You can read more about Active Record in the {Active Record Basics}[https://guides.rubyonrails.org/active_record_basics.html] guide.
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
            A short rundown of some of the major features:
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
            * Automated mapping between classes and tables, attributes and columns.
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
              {Learn more}[link:classes/ActiveRecord/Base.html]
         
     | 
| 
      
 22 
     | 
    
         
            +
                class Product < ActiveRecord::Base
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
       26 
24 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
            The Product class is automatically mapped to the table named "products",
         
     | 
| 
       28 
     | 
    
         
            -
            which might look like this:
         
     | 
| 
      
 25 
     | 
    
         
            +
              The Product class is automatically mapped to the table named "products",
         
     | 
| 
      
 26 
     | 
    
         
            +
              which might look like this:
         
     | 
| 
       29 
27 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 28 
     | 
    
         
            +
                CREATE TABLE products (
         
     | 
| 
      
 29 
     | 
    
         
            +
                  id bigint NOT NULL auto_increment,
         
     | 
| 
      
 30 
     | 
    
         
            +
                  name varchar(255),
         
     | 
| 
      
 31 
     | 
    
         
            +
                  PRIMARY KEY  (id)
         
     | 
| 
      
 32 
     | 
    
         
            +
                );
         
     | 
| 
       35 
33 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
            This would also define the following accessors: <tt>Product#name</tt> and
         
     | 
| 
       37 
     | 
    
         
            -
            <tt>Product#name=(new_name)</tt>.
         
     | 
| 
      
 34 
     | 
    
         
            +
              This would also define the following accessors: <tt>Product#name</tt> and
         
     | 
| 
      
 35 
     | 
    
         
            +
              <tt>Product#name=(new_name)</tt>.
         
     | 
| 
       38 
36 
     | 
    
         | 
| 
      
 37 
     | 
    
         
            +
              {Learn more}[link:classes/ActiveRecord/Base.html]
         
     | 
| 
       39 
38 
     | 
    
         | 
| 
       40 
39 
     | 
    
         
             
            * Associations between objects defined by simple class methods.
         
     | 
| 
       41 
40 
     | 
    
         | 
| 
         @@ -140,7 +139,7 @@ This would also define the following accessors: <tt>Product#name</tt> and 
     | 
|
| 
       140 
139 
     | 
    
         | 
| 
       141 
140 
     | 
    
         
             
            * Database agnostic schema management with Migrations.
         
     | 
| 
       142 
141 
     | 
    
         | 
| 
       143 
     | 
    
         
            -
                class AddSystemSettings < ActiveRecord::Migration[ 
     | 
| 
      
 142 
     | 
    
         
            +
                class AddSystemSettings < ActiveRecord::Migration[7.1]
         
     | 
| 
       144 
143 
     | 
    
         
             
                  def up
         
     | 
| 
       145 
144 
     | 
    
         
             
                    create_table :system_settings do |t|
         
     | 
| 
       146 
145 
     | 
    
         
             
                      t.string  :name
         
     | 
| 
         @@ -167,6 +166,7 @@ Active Record is an implementation of the object-relational mapping (ORM) 
     | 
|
| 
       167 
166 
     | 
    
         
             
            pattern[https://www.martinfowler.com/eaaCatalog/activeRecord.html] by the same
         
     | 
| 
       168 
167 
     | 
    
         
             
            name described by Martin Fowler:
         
     | 
| 
       169 
168 
     | 
    
         | 
| 
      
 169 
     | 
    
         
            +
            >>>
         
     | 
| 
       170 
170 
     | 
    
         
             
              "An object that wraps a row in a database table or view,
         
     | 
| 
       171 
171 
     | 
    
         
             
              encapsulates the database access, and adds domain logic on that data."
         
     | 
| 
       172 
172 
     | 
    
         | 
| 
         @@ -192,7 +192,7 @@ The latest version of Active Record can be installed with RubyGems: 
     | 
|
| 
       192 
192 
     | 
    
         | 
| 
       193 
193 
     | 
    
         
             
              $ gem install activerecord
         
     | 
| 
       194 
194 
     | 
    
         | 
| 
       195 
     | 
    
         
            -
            Source code can be downloaded as part of the Rails project on GitHub:
         
     | 
| 
      
 195 
     | 
    
         
            +
            Source code can be downloaded as part of the \Rails project on GitHub:
         
     | 
| 
       196 
196 
     | 
    
         | 
| 
       197 
197 
     | 
    
         
             
            * https://github.com/rails/rails/tree/main/activerecord
         
     | 
| 
       198 
198 
     | 
    
         | 
| 
         @@ -210,7 +210,7 @@ API documentation is at: 
     | 
|
| 
       210 
210 
     | 
    
         | 
| 
       211 
211 
     | 
    
         
             
            * https://api.rubyonrails.org
         
     | 
| 
       212 
212 
     | 
    
         | 
| 
       213 
     | 
    
         
            -
            Bug reports for the Ruby on Rails project can be filed here:
         
     | 
| 
      
 213 
     | 
    
         
            +
            Bug reports for the Ruby on \Rails project can be filed here:
         
     | 
| 
       214 
214 
     | 
    
         | 
| 
       215 
215 
     | 
    
         
             
            * https://github.com/rails/rails/issues
         
     | 
| 
       216 
216 
     | 
    
         | 
| 
         @@ -4,7 +4,7 @@ module ActiveRecord 
     | 
|
| 
       4 
4 
     | 
    
         
             
              # See ActiveRecord::Aggregations::ClassMethods for documentation
         
     | 
| 
       5 
5 
     | 
    
         
             
              module Aggregations
         
     | 
| 
       6 
6 
     | 
    
         
             
                def initialize_dup(*) # :nodoc:
         
     | 
| 
       7 
     | 
    
         
            -
                  @aggregation_cache =  
     | 
| 
      
 7 
     | 
    
         
            +
                  @aggregation_cache = @aggregation_cache.dup
         
     | 
| 
       8 
8 
     | 
    
         
             
                  super
         
     | 
| 
       9 
9 
     | 
    
         
             
                end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
         @@ -19,10 +19,12 @@ module ActiveRecord 
     | 
|
| 
       19 
19 
     | 
    
         
             
                  end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                  def init_internals
         
     | 
| 
       22 
     | 
    
         
            -
                    @aggregation_cache = {}
         
     | 
| 
       23 
22 
     | 
    
         
             
                    super
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @aggregation_cache = {}
         
     | 
| 
       24 
24 
     | 
    
         
             
                  end
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
                  # = Active Record \Aggregations
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #
         
     | 
| 
       26 
28 
     | 
    
         
             
                  # Active Record implements aggregation through a macro-like class method called #composed_of
         
     | 
| 
       27 
29 
     | 
    
         
             
                  # for representing attributes as value objects. It expresses relationships like "Account [is]
         
     | 
| 
       28 
30 
     | 
    
         
             
                  # composed of Money [among other things]" or "Person [is] composed of [an] address". Each call
         
     | 
| 
         @@ -32,8 +34,8 @@ module ActiveRecord 
     | 
|
| 
       32 
34 
     | 
    
         
             
                  # the database).
         
     | 
| 
       33 
35 
     | 
    
         
             
                  #
         
     | 
| 
       34 
36 
     | 
    
         
             
                  #   class Customer < ActiveRecord::Base
         
     | 
| 
       35 
     | 
    
         
            -
                  #     composed_of :balance, class_name: "Money", mapping:  
     | 
| 
       36 
     | 
    
         
            -
                  #     composed_of :address, mapping:  
     | 
| 
      
 37 
     | 
    
         
            +
                  #     composed_of :balance, class_name: "Money", mapping: { balance: :amount }
         
     | 
| 
      
 38 
     | 
    
         
            +
                  #     composed_of :address, mapping: { address_street: :street, address_city: :city }
         
     | 
| 
       37 
39 
     | 
    
         
             
                  #   end
         
     | 
| 
       38 
40 
     | 
    
         
             
                  #
         
     | 
| 
       39 
41 
     | 
    
         
             
                  # The customer class now has the following methods to manipulate the value objects:
         
     | 
| 
         @@ -150,7 +152,7 @@ module ActiveRecord 
     | 
|
| 
       150 
152 
     | 
    
         
             
                  #   class NetworkResource < ActiveRecord::Base
         
     | 
| 
       151 
153 
     | 
    
         
             
                  #     composed_of :cidr,
         
     | 
| 
       152 
154 
     | 
    
         
             
                  #                 class_name: 'NetAddr::CIDR',
         
     | 
| 
       153 
     | 
    
         
            -
                  #                 mapping:  
     | 
| 
      
 155 
     | 
    
         
            +
                  #                 mapping: { network_address: :network, cidr_range: :bits },
         
     | 
| 
       154 
156 
     | 
    
         
             
                  #                 allow_nil: true,
         
     | 
| 
       155 
157 
     | 
    
         
             
                  #                 constructor: Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") },
         
     | 
| 
       156 
158 
     | 
    
         
             
                  #                 converter: Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) }
         
     | 
| 
         @@ -188,10 +190,10 @@ module ActiveRecord 
     | 
|
| 
       188 
190 
     | 
    
         
             
                    #   to the Address class, but if the real class name is +CompanyAddress+, you'll have to specify it
         
     | 
| 
       189 
191 
     | 
    
         
             
                    #   with this option.
         
     | 
| 
       190 
192 
     | 
    
         
             
                    # * <tt>:mapping</tt> - Specifies the mapping of entity attributes to attributes of the value
         
     | 
| 
       191 
     | 
    
         
            -
                    #   object. Each mapping is represented as  
     | 
| 
       192 
     | 
    
         
            -
                    #   entity attribute and the  
     | 
| 
      
 193 
     | 
    
         
            +
                    #   object. Each mapping is represented as a key-value pair where the key is the name of the
         
     | 
| 
      
 194 
     | 
    
         
            +
                    #   entity attribute and the value is the name of the attribute in the value object. The
         
     | 
| 
       193 
195 
     | 
    
         
             
                    #   order in which mappings are defined determines the order in which attributes are sent to the
         
     | 
| 
       194 
     | 
    
         
            -
                    #   value class constructor.
         
     | 
| 
      
 196 
     | 
    
         
            +
                    #   value class constructor. The mapping can be written as a hash or as an array of pairs.
         
     | 
| 
       195 
197 
     | 
    
         
             
                    # * <tt>:allow_nil</tt> - Specifies that the value object will not be instantiated when all mapped
         
     | 
| 
       196 
198 
     | 
    
         
             
                    #   attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all
         
     | 
| 
       197 
199 
     | 
    
         
             
                    #   mapped attributes.
         
     | 
| 
         @@ -208,14 +210,15 @@ module ActiveRecord 
     | 
|
| 
       208 
210 
     | 
    
         
             
                    #   can return +nil+ to skip the assignment.
         
     | 
| 
       209 
211 
     | 
    
         
             
                    #
         
     | 
| 
       210 
212 
     | 
    
         
             
                    # Option examples:
         
     | 
| 
       211 
     | 
    
         
            -
                    #   composed_of :temperature, mapping:  
     | 
| 
       212 
     | 
    
         
            -
                    #   composed_of :balance, class_name: "Money", mapping:  
     | 
| 
      
 213 
     | 
    
         
            +
                    #   composed_of :temperature, mapping: { reading: :celsius }
         
     | 
| 
      
 214 
     | 
    
         
            +
                    #   composed_of :balance, class_name: "Money", mapping: { balance: :amount }
         
     | 
| 
      
 215 
     | 
    
         
            +
                    #   composed_of :address, mapping: { address_street: :street, address_city: :city }
         
     | 
| 
       213 
216 
     | 
    
         
             
                    #   composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
         
     | 
| 
       214 
217 
     | 
    
         
             
                    #   composed_of :gps_location
         
     | 
| 
       215 
218 
     | 
    
         
             
                    #   composed_of :gps_location, allow_nil: true
         
     | 
| 
       216 
219 
     | 
    
         
             
                    #   composed_of :ip_address,
         
     | 
| 
       217 
220 
     | 
    
         
             
                    #               class_name: 'IPAddr',
         
     | 
| 
       218 
     | 
    
         
            -
                    #               mapping:  
     | 
| 
      
 221 
     | 
    
         
            +
                    #               mapping: { ip: :to_i },
         
     | 
| 
       219 
222 
     | 
    
         
             
                    #               constructor: Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
         
     | 
| 
       220 
223 
     | 
    
         
             
                    #               converter: Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }
         
     | 
| 
       221 
224 
     | 
    
         
             
                    #
         
     | 
| 
         @@ -249,7 +252,7 @@ module ActiveRecord 
     | 
|
| 
       249 
252 
     | 
    
         
             
                            object = constructor.respond_to?(:call) ?
         
     | 
| 
       250 
253 
     | 
    
         
             
                              constructor.call(*attrs) :
         
     | 
| 
       251 
254 
     | 
    
         
             
                              class_name.constantize.send(constructor, *attrs)
         
     | 
| 
       252 
     | 
    
         
            -
                            @aggregation_cache[name] = object
         
     | 
| 
      
 255 
     | 
    
         
            +
                            @aggregation_cache[name] = object.freeze
         
     | 
| 
       253 
256 
     | 
    
         
             
                          end
         
     | 
| 
       254 
257 
     | 
    
         
             
                          @aggregation_cache[name]
         
     | 
| 
       255 
258 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -264,7 +267,7 @@ module ActiveRecord 
     | 
|
| 
       264 
267 
     | 
    
         
             
                          end
         
     | 
| 
       265 
268 
     | 
    
         | 
| 
       266 
269 
     | 
    
         
             
                          hash_from_multiparameter_assignment = part.is_a?(Hash) &&
         
     | 
| 
       267 
     | 
    
         
            -
                            part. 
     | 
| 
      
 270 
     | 
    
         
            +
                            part.keys.all?(Integer)
         
     | 
| 
       268 
271 
     | 
    
         
             
                          if hash_from_multiparameter_assignment
         
     | 
| 
       269 
272 
     | 
    
         
             
                            raise ArgumentError unless part.size == part.each_key.max
         
     | 
| 
       270 
273 
     | 
    
         
             
                            part = klass.new(*part.sort.map(&:last))
         
     | 
| 
         @@ -275,7 +278,7 @@ module ActiveRecord 
     | 
|
| 
       275 
278 
     | 
    
         
             
                            @aggregation_cache[name] = nil
         
     | 
| 
       276 
279 
     | 
    
         
             
                          else
         
     | 
| 
       277 
280 
     | 
    
         
             
                            mapping.each { |key, value| write_attribute(key, part.send(value)) }
         
     | 
| 
       278 
     | 
    
         
            -
                            @aggregation_cache[name] = part.freeze
         
     | 
| 
      
 281 
     | 
    
         
            +
                            @aggregation_cache[name] = part.dup.freeze
         
     | 
| 
       279 
282 
     | 
    
         
             
                          end
         
     | 
| 
       280 
283 
     | 
    
         
             
                        end
         
     | 
| 
       281 
284 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -16,7 +16,7 @@ module ActiveRecord 
     | 
|
| 
       16 
16 
     | 
    
         
             
                end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                %w(insert insert_all insert! insert_all! upsert upsert_all).each do |method|
         
     | 
| 
       19 
     | 
    
         
            -
                  class_eval <<~RUBY
         
     | 
| 
      
 19 
     | 
    
         
            +
                  class_eval <<~RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
       20 
20 
     | 
    
         
             
                    def #{method}(attributes, **kwargs)
         
     | 
| 
       21 
21 
     | 
    
         
             
                      if @association.reflection.through_reflection?
         
     | 
| 
       22 
22 
     | 
    
         
             
                        raise ArgumentError, "Bulk insert or upsert is currently not supported for has_many through association"
         
     | 
| 
         @@ -27,16 +27,6 @@ module ActiveRecord 
     | 
|
| 
       27 
27 
     | 
    
         
             
                  RUBY
         
     | 
| 
       28 
28 
     | 
    
         
             
                end
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                def build(attributes = nil, &block)
         
     | 
| 
       31 
     | 
    
         
            -
                  if attributes.is_a?(Array)
         
     | 
| 
       32 
     | 
    
         
            -
                    attributes.collect { |attr| build(attr, &block) }
         
     | 
| 
       33 
     | 
    
         
            -
                  else
         
     | 
| 
       34 
     | 
    
         
            -
                    block = current_scope_restoring_block(&block)
         
     | 
| 
       35 
     | 
    
         
            -
                    scoping { _new(attributes, &block) }
         
     | 
| 
       36 
     | 
    
         
            -
                  end
         
     | 
| 
       37 
     | 
    
         
            -
                end
         
     | 
| 
       38 
     | 
    
         
            -
                alias new build
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
30 
     | 
    
         
             
                private
         
     | 
| 
       41 
31 
     | 
    
         
             
                  def _new(attributes, &block)
         
     | 
| 
       42 
32 
     | 
    
         
             
                    @association.build(attributes, &block)
         
     | 
| 
         @@ -19,7 +19,7 @@ module ActiveRecord 
     | 
|
| 
       19 
19 
     | 
    
         
             
                # Associations in Active Record are middlemen between the object that
         
     | 
| 
       20 
20 
     | 
    
         
             
                # holds the association, known as the <tt>owner</tt>, and the associated
         
     | 
| 
       21 
21 
     | 
    
         
             
                # result set, known as the <tt>target</tt>. Association metadata is available in
         
     | 
| 
       22 
     | 
    
         
            -
                # <tt>reflection</tt>, which is an instance of  
     | 
| 
      
 22 
     | 
    
         
            +
                # <tt>reflection</tt>, which is an instance of +ActiveRecord::Reflection::AssociationReflection+.
         
     | 
| 
       23 
23 
     | 
    
         
             
                #
         
     | 
| 
       24 
24 
     | 
    
         
             
                # For example, given
         
     | 
| 
       25 
25 
     | 
    
         
             
                #
         
     | 
| 
         @@ -32,8 +32,8 @@ module ActiveRecord 
     | 
|
| 
       32 
32 
     | 
    
         
             
                # The association of <tt>blog.posts</tt> has the object +blog+ as its
         
     | 
| 
       33 
33 
     | 
    
         
             
                # <tt>owner</tt>, the collection of its posts as <tt>target</tt>, and
         
     | 
| 
       34 
34 
     | 
    
         
             
                # the <tt>reflection</tt> object represents a <tt>:has_many</tt> macro.
         
     | 
| 
       35 
     | 
    
         
            -
                class Association  
     | 
| 
       36 
     | 
    
         
            -
                  attr_reader :owner, :target, :reflection
         
     | 
| 
      
 35 
     | 
    
         
            +
                class Association # :nodoc:
         
     | 
| 
      
 36 
     | 
    
         
            +
                  attr_reader :owner, :target, :reflection, :disable_joins
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         
             
                  delegate :options, to: :reflection
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
         @@ -41,9 +41,12 @@ module ActiveRecord 
     | 
|
| 
       41 
41 
     | 
    
         
             
                    reflection.check_validity!
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
                    @owner, @reflection = owner, reflection
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @disable_joins = @reflection.options[:disable_joins] || false
         
     | 
| 
       44 
45 
     | 
    
         | 
| 
       45 
46 
     | 
    
         
             
                    reset
         
     | 
| 
       46 
47 
     | 
    
         
             
                    reset_scope
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    @skip_strict_loading = nil
         
     | 
| 
       47 
50 
     | 
    
         
             
                  end
         
     | 
| 
       48 
51 
     | 
    
         | 
| 
       49 
52 
     | 
    
         
             
                  # Resets the \loaded flag to +false+ and sets the \target to +nil+.
         
     | 
| 
         @@ -51,7 +54,6 @@ module ActiveRecord 
     | 
|
| 
       51 
54 
     | 
    
         
             
                    @loaded = false
         
     | 
| 
       52 
55 
     | 
    
         
             
                    @target = nil
         
     | 
| 
       53 
56 
     | 
    
         
             
                    @stale_state = nil
         
     | 
| 
       54 
     | 
    
         
            -
                    @inversed = false
         
     | 
| 
       55 
57 
     | 
    
         
             
                  end
         
     | 
| 
       56 
58 
     | 
    
         | 
| 
       57 
59 
     | 
    
         
             
                  def reset_negative_cache # :nodoc:
         
     | 
| 
         @@ -77,7 +79,6 @@ module ActiveRecord 
     | 
|
| 
       77 
79 
     | 
    
         
             
                  def loaded!
         
     | 
| 
       78 
80 
     | 
    
         
             
                    @loaded = true
         
     | 
| 
       79 
81 
     | 
    
         
             
                    @stale_state = stale_state
         
     | 
| 
       80 
     | 
    
         
            -
                    @inversed = false
         
     | 
| 
       81 
82 
     | 
    
         
             
                  end
         
     | 
| 
       82 
83 
     | 
    
         | 
| 
       83 
84 
     | 
    
         
             
                  # The target is stale if the target no longer points to the record(s) that the
         
     | 
| 
         @@ -87,7 +88,7 @@ module ActiveRecord 
     | 
|
| 
       87 
88 
     | 
    
         
             
                  #
         
     | 
| 
       88 
89 
     | 
    
         
             
                  # Note that if the target has not been loaded, it is not considered stale.
         
     | 
| 
       89 
90 
     | 
    
         
             
                  def stale_target?
         
     | 
| 
       90 
     | 
    
         
            -
                     
     | 
| 
      
 91 
     | 
    
         
            +
                    loaded? && @stale_state != stale_state
         
     | 
| 
       91 
92 
     | 
    
         
             
                  end
         
     | 
| 
       92 
93 
     | 
    
         | 
| 
       93 
94 
     | 
    
         
             
                  # Sets the target of this association to <tt>\target</tt>, and the \loaded flag to +true+.
         
     | 
| 
         @@ -97,8 +98,12 @@ module ActiveRecord 
     | 
|
| 
       97 
98 
     | 
    
         
             
                  end
         
     | 
| 
       98 
99 
     | 
    
         | 
| 
       99 
100 
     | 
    
         
             
                  def scope
         
     | 
| 
       100 
     | 
    
         
            -
                    if  
     | 
| 
      
 101 
     | 
    
         
            +
                    if disable_joins
         
     | 
| 
      
 102 
     | 
    
         
            +
                      DisableJoinsAssociationScope.create.scope(self)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    elsif (scope = klass.current_scope) && scope.try(:proxy_association) == self
         
     | 
| 
       101 
104 
     | 
    
         
             
                      scope.spawn
         
     | 
| 
      
 105 
     | 
    
         
            +
                    elsif scope = klass.global_current_scope
         
     | 
| 
      
 106 
     | 
    
         
            +
                      target_scope.merge!(association_scope).merge!(scope)
         
     | 
| 
       102 
107 
     | 
    
         
             
                    else
         
     | 
| 
       103 
108 
     | 
    
         
             
                      target_scope.merge!(association_scope)
         
     | 
| 
       104 
109 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -132,15 +137,11 @@ module ActiveRecord 
     | 
|
| 
       132 
137 
     | 
    
         | 
| 
       133 
138 
     | 
    
         
             
                  def inversed_from(record)
         
     | 
| 
       134 
139 
     | 
    
         
             
                    self.target = record
         
     | 
| 
       135 
     | 
    
         
            -
                    @inversed = !!record
         
     | 
| 
       136 
140 
     | 
    
         
             
                  end
         
     | 
| 
       137 
141 
     | 
    
         | 
| 
       138 
142 
     | 
    
         
             
                  def inversed_from_queries(record)
         
     | 
| 
       139 
143 
     | 
    
         
             
                    if inversable?(record)
         
     | 
| 
       140 
144 
     | 
    
         
             
                      self.target = record
         
     | 
| 
       141 
     | 
    
         
            -
                      @inversed = true
         
     | 
| 
       142 
     | 
    
         
            -
                    else
         
     | 
| 
       143 
     | 
    
         
            -
                      @inversed = false
         
     | 
| 
       144 
145 
     | 
    
         
             
                    end
         
     | 
| 
       145 
146 
     | 
    
         
             
                  end
         
     | 
| 
       146 
147 
     | 
    
         | 
| 
         @@ -191,7 +192,7 @@ module ActiveRecord 
     | 
|
| 
       191 
192 
     | 
    
         
             
                    @reflection = @owner.class._reflect_on_association(reflection_name)
         
     | 
| 
       192 
193 
     | 
    
         
             
                  end
         
     | 
| 
       193 
194 
     | 
    
         | 
| 
       194 
     | 
    
         
            -
                  def initialize_attributes(record, except_from_scope_attributes = nil)  
     | 
| 
      
 195 
     | 
    
         
            +
                  def initialize_attributes(record, except_from_scope_attributes = nil) # :nodoc:
         
     | 
| 
       195 
196 
     | 
    
         
             
                    except_from_scope_attributes ||= {}
         
     | 
| 
       196 
197 
     | 
    
         
             
                    skip_assign = [reflection.foreign_key, reflection.type].compact
         
     | 
| 
       197 
198 
     | 
    
         
             
                    assigned_keys = record.changed_attribute_names_to_save
         
     | 
| 
         @@ -210,8 +211,14 @@ module ActiveRecord 
     | 
|
| 
       210 
211 
     | 
    
         
             
                  end
         
     | 
| 
       211 
212 
     | 
    
         | 
| 
       212 
213 
     | 
    
         
             
                  private
         
     | 
| 
      
 214 
     | 
    
         
            +
                    # Reader and writer methods call this so that consistent errors are presented
         
     | 
| 
      
 215 
     | 
    
         
            +
                    # when the association target class does not exist.
         
     | 
| 
      
 216 
     | 
    
         
            +
                    def ensure_klass_exists!
         
     | 
| 
      
 217 
     | 
    
         
            +
                      klass
         
     | 
| 
      
 218 
     | 
    
         
            +
                    end
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
       213 
220 
     | 
    
         
             
                    def find_target
         
     | 
| 
       214 
     | 
    
         
            -
                      if  
     | 
| 
      
 221 
     | 
    
         
            +
                      if violates_strict_loading?
         
     | 
| 
       215 
222 
     | 
    
         
             
                        Base.strict_loading_violation!(owner: owner.class, reflection: reflection)
         
     | 
| 
       216 
223 
     | 
    
         
             
                      end
         
     | 
| 
       217 
224 
     | 
    
         | 
| 
         @@ -224,13 +231,32 @@ module ActiveRecord 
     | 
|
| 
       224 
231 
     | 
    
         
             
                      end
         
     | 
| 
       225 
232 
     | 
    
         | 
| 
       226 
233 
     | 
    
         
             
                      binds = AssociationScope.get_bind_values(owner, reflection.chain)
         
     | 
| 
       227 
     | 
    
         
            -
                      sc.execute(binds, klass.connection)  
     | 
| 
      
 234 
     | 
    
         
            +
                      sc.execute(binds, klass.connection) do |record|
         
     | 
| 
      
 235 
     | 
    
         
            +
                        set_inverse_instance(record)
         
     | 
| 
      
 236 
     | 
    
         
            +
                        if owner.strict_loading_n_plus_one_only? && reflection.macro == :has_many
         
     | 
| 
      
 237 
     | 
    
         
            +
                          record.strict_loading!
         
     | 
| 
      
 238 
     | 
    
         
            +
                        else
         
     | 
| 
      
 239 
     | 
    
         
            +
                          record.strict_loading!(false, mode: owner.strict_loading_mode)
         
     | 
| 
      
 240 
     | 
    
         
            +
                        end
         
     | 
| 
      
 241 
     | 
    
         
            +
                      end
         
     | 
| 
       228 
242 
     | 
    
         
             
                    end
         
     | 
| 
       229 
243 
     | 
    
         | 
| 
       230 
     | 
    
         
            -
                    def  
     | 
| 
      
 244 
     | 
    
         
            +
                    def skip_strict_loading(&block)
         
     | 
| 
      
 245 
     | 
    
         
            +
                      skip_strict_loading_was = @skip_strict_loading
         
     | 
| 
      
 246 
     | 
    
         
            +
                      @skip_strict_loading = true
         
     | 
| 
      
 247 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 248 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 249 
     | 
    
         
            +
                      @skip_strict_loading = skip_strict_loading_was
         
     | 
| 
      
 250 
     | 
    
         
            +
                    end
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
                    def violates_strict_loading?
         
     | 
| 
      
 253 
     | 
    
         
            +
                      return if @skip_strict_loading
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
                      return unless owner.validation_context.nil?
         
     | 
| 
      
 256 
     | 
    
         
            +
             
     | 
| 
       231 
257 
     | 
    
         
             
                      return reflection.strict_loading? if reflection.options.key?(:strict_loading)
         
     | 
| 
       232 
258 
     | 
    
         | 
| 
       233 
     | 
    
         
            -
                      owner.strict_loading?
         
     | 
| 
      
 259 
     | 
    
         
            +
                      owner.strict_loading? && !owner.strict_loading_n_plus_one_only?
         
     | 
| 
       234 
260 
     | 
    
         
             
                    end
         
     | 
| 
       235 
261 
     | 
    
         | 
| 
       236 
262 
     | 
    
         
             
                    # The scope for this association.
         
     | 
| 
         @@ -241,7 +267,11 @@ module ActiveRecord 
     | 
|
| 
       241 
267 
     | 
    
         
             
                    # actually gets built.
         
     | 
| 
       242 
268 
     | 
    
         
             
                    def association_scope
         
     | 
| 
       243 
269 
     | 
    
         
             
                      if klass
         
     | 
| 
       244 
     | 
    
         
            -
                        @association_scope ||=  
     | 
| 
      
 270 
     | 
    
         
            +
                        @association_scope ||= if disable_joins
         
     | 
| 
      
 271 
     | 
    
         
            +
                          DisableJoinsAssociationScope.scope(self)
         
     | 
| 
      
 272 
     | 
    
         
            +
                        else
         
     | 
| 
      
 273 
     | 
    
         
            +
                          AssociationScope.scope(self)
         
     | 
| 
      
 274 
     | 
    
         
            +
                        end
         
     | 
| 
       245 
275 
     | 
    
         
             
                      end
         
     | 
| 
       246 
276 
     | 
    
         
             
                    end
         
     | 
| 
       247 
277 
     | 
    
         | 
| 
         @@ -273,7 +303,7 @@ module ActiveRecord 
     | 
|
| 
       273 
303 
     | 
    
         | 
| 
       274 
304 
     | 
    
         
             
                    # Raises ActiveRecord::AssociationTypeMismatch unless +record+ is of
         
     | 
| 
       275 
305 
     | 
    
         
             
                    # the kind of the class of the associated objects. Meant to be used as
         
     | 
| 
       276 
     | 
    
         
            -
                    # a  
     | 
| 
      
 306 
     | 
    
         
            +
                    # a safety check when you are about to assign an associated record.
         
     | 
| 
       277 
307 
     | 
    
         
             
                    def raise_on_type_mismatch!(record)
         
     | 
| 
       278 
308 
     | 
    
         
             
                      unless record.is_a?(reflection.klass)
         
     | 
| 
       279 
309 
     | 
    
         
             
                        fresh_class = reflection.class_name.safe_constantize
         
     | 
| 
         @@ -306,7 +336,8 @@ module ActiveRecord 
     | 
|
| 
       306 
336 
     | 
    
         | 
| 
       307 
337 
     | 
    
         
             
                    # Returns true if record contains the foreign_key
         
     | 
| 
       308 
338 
     | 
    
         
             
                    def foreign_key_for?(record)
         
     | 
| 
       309 
     | 
    
         
            -
                       
     | 
| 
      
 339 
     | 
    
         
            +
                      foreign_key = Array(reflection.foreign_key)
         
     | 
| 
      
 340 
     | 
    
         
            +
                      foreign_key.all? { |key| record._has_attribute?(key) }
         
     | 
| 
       310 
341 
     | 
    
         
             
                    end
         
     | 
| 
       311 
342 
     | 
    
         | 
| 
       312 
343 
     | 
    
         
             
                    # This should be implemented to return the values of the relevant key(s) on the owner,
         
     | 
| 
         @@ -2,7 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Associations
         
     | 
| 
       5 
     | 
    
         
            -
                class AssociationScope  
     | 
| 
      
 5 
     | 
    
         
            +
                class AssociationScope # :nodoc:
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.scope(association)
         
     | 
| 
       7 
7 
     | 
    
         
             
                    INSTANCE.scope(association)
         
     | 
| 
       8 
8 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -35,7 +35,7 @@ module ActiveRecord 
     | 
|
| 
       35 
35 
     | 
    
         
             
                    binds = []
         
     | 
| 
       36 
36 
     | 
    
         
             
                    last_reflection = chain.last
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                    binds 
     | 
| 
      
 38 
     | 
    
         
            +
                    binds.push(*last_reflection.join_id_for(owner))
         
     | 
| 
       39 
39 
     | 
    
         
             
                    if last_reflection.type
         
     | 
| 
       40 
40 
     | 
    
         
             
                      binds << owner.class.polymorphic_name
         
     | 
| 
       41 
41 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -56,12 +56,15 @@ module ActiveRecord 
     | 
|
| 
       56 
56 
     | 
    
         
             
                    end
         
     | 
| 
       57 
57 
     | 
    
         | 
| 
       58 
58 
     | 
    
         
             
                    def last_chain_scope(scope, reflection, owner)
         
     | 
| 
       59 
     | 
    
         
            -
                      primary_key = reflection.join_primary_key
         
     | 
| 
       60 
     | 
    
         
            -
                      foreign_key = reflection.join_foreign_key
         
     | 
| 
      
 59 
     | 
    
         
            +
                      primary_key = Array(reflection.join_primary_key)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      foreign_key = Array(reflection.join_foreign_key)
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
       62 
62 
     | 
    
         
             
                      table = reflection.aliased_table
         
     | 
| 
       63 
     | 
    
         
            -
                       
     | 
| 
       64 
     | 
    
         
            -
                       
     | 
| 
      
 63 
     | 
    
         
            +
                      primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      primary_key_foreign_key_pairs.each do |join_key, foreign_key|
         
     | 
| 
      
 65 
     | 
    
         
            +
                        value = transform_value(owner._read_attribute(foreign_key))
         
     | 
| 
      
 66 
     | 
    
         
            +
                        scope = apply_scope(scope, table, join_key, value)
         
     | 
| 
      
 67 
     | 
    
         
            +
                      end
         
     | 
| 
       65 
68 
     | 
    
         | 
| 
       66 
69 
     | 
    
         
             
                      if reflection.type
         
     | 
| 
       67 
70 
     | 
    
         
             
                        polymorphic_type = transform_value(owner.class.polymorphic_name)
         
     | 
| 
         @@ -76,19 +79,23 @@ module ActiveRecord 
     | 
|
| 
       76 
79 
     | 
    
         
             
                    end
         
     | 
| 
       77 
80 
     | 
    
         | 
| 
       78 
81 
     | 
    
         
             
                    def next_chain_scope(scope, reflection, next_reflection)
         
     | 
| 
       79 
     | 
    
         
            -
                      primary_key = reflection.join_primary_key
         
     | 
| 
       80 
     | 
    
         
            -
                      foreign_key = reflection.join_foreign_key
         
     | 
| 
      
 82 
     | 
    
         
            +
                      primary_key = Array(reflection.join_primary_key)
         
     | 
| 
      
 83 
     | 
    
         
            +
                      foreign_key = Array(reflection.join_foreign_key)
         
     | 
| 
       81 
84 
     | 
    
         | 
| 
       82 
85 
     | 
    
         
             
                      table = reflection.aliased_table
         
     | 
| 
       83 
86 
     | 
    
         
             
                      foreign_table = next_reflection.aliased_table
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                      primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      constraints = primary_key_foreign_key_pairs.map do |join_primary_key, foreign_key|
         
     | 
| 
      
 90 
     | 
    
         
            +
                        table[join_primary_key].eq(foreign_table[foreign_key])
         
     | 
| 
      
 91 
     | 
    
         
            +
                      end.inject(&:and)
         
     | 
| 
       85 
92 
     | 
    
         | 
| 
       86 
93 
     | 
    
         
             
                      if reflection.type
         
     | 
| 
       87 
94 
     | 
    
         
             
                        value = transform_value(next_reflection.klass.polymorphic_name)
         
     | 
| 
       88 
95 
     | 
    
         
             
                        scope = apply_scope(scope, table, reflection.type, value)
         
     | 
| 
       89 
96 
     | 
    
         
             
                      end
         
     | 
| 
       90 
97 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
                      scope.joins!(join(foreign_table,  
     | 
| 
      
 98 
     | 
    
         
            +
                      scope.joins!(join(foreign_table, constraints))
         
     | 
| 
       92 
99 
     | 
    
         
             
                    end
         
     | 
| 
       93 
100 
     | 
    
         | 
| 
       94 
101 
     | 
    
         
             
                    class ReflectionProxy < SimpleDelegator # :nodoc:
         
     | 
| 
         @@ -123,8 +130,6 @@ module ActiveRecord 
     | 
|
| 
       123 
130 
     | 
    
         | 
| 
       124 
131 
     | 
    
         
             
                      chain_head = chain.first
         
     | 
| 
       125 
132 
     | 
    
         
             
                      chain.reverse_each do |reflection|
         
     | 
| 
       126 
     | 
    
         
            -
                        # Exclude the scope of the association itself, because that
         
     | 
| 
       127 
     | 
    
         
            -
                        # was already merged in the #scope method.
         
     | 
| 
       128 
133 
     | 
    
         
             
                        reflection.constraints.each do |scope_chain_item|
         
     | 
| 
       129 
134 
     | 
    
         
             
                          item = eval_scope(reflection, scope_chain_item, owner)
         
     | 
| 
       130 
135 
     | 
    
         | 
| 
         @@ -3,7 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Associations
         
     | 
| 
       5 
5 
     | 
    
         
             
                # = Active Record Belongs To Association
         
     | 
| 
       6 
     | 
    
         
            -
                class BelongsToAssociation < SingularAssociation  
     | 
| 
      
 6 
     | 
    
         
            +
                class BelongsToAssociation < SingularAssociation # :nodoc:
         
     | 
| 
       7 
7 
     | 
    
         
             
                  def handle_dependency
         
     | 
| 
       8 
8 
     | 
    
         
             
                    return unless load_target
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
         @@ -11,8 +11,13 @@ module ActiveRecord 
     | 
|
| 
       11 
11 
     | 
    
         
             
                    when :destroy
         
     | 
| 
       12 
12 
     | 
    
         
             
                      raise ActiveRecord::Rollback unless target.destroy
         
     | 
| 
       13 
13 
     | 
    
         
             
                    when :destroy_async
         
     | 
| 
       14 
     | 
    
         
            -
                       
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
                      if reflection.foreign_key.is_a?(Array)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        primary_key_column = reflection.active_record_primary_key.map(&:to_sym)
         
     | 
| 
      
 16 
     | 
    
         
            +
                        id = reflection.foreign_key.map { |col| owner.public_send(col.to_sym) }
         
     | 
| 
      
 17 
     | 
    
         
            +
                      else
         
     | 
| 
      
 18 
     | 
    
         
            +
                        primary_key_column = reflection.active_record_primary_key.to_sym
         
     | 
| 
      
 19 
     | 
    
         
            +
                        id = owner.public_send(reflection.foreign_key.to_sym)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
       16 
21 
     | 
    
         | 
| 
       17 
22 
     | 
    
         
             
                      enqueue_destroy_association(
         
     | 
| 
       18 
23 
     | 
    
         
             
                        owner_model_name: owner.class.to_s,
         
     | 
| 
         @@ -55,7 +60,8 @@ module ActiveRecord 
     | 
|
| 
       55 
60 
     | 
    
         | 
| 
       56 
61 
     | 
    
         
             
                  def decrement_counters_before_last_save
         
     | 
| 
       57 
62 
     | 
    
         
             
                    if reflection.polymorphic?
         
     | 
| 
       58 
     | 
    
         
            -
                       
     | 
| 
      
 63 
     | 
    
         
            +
                      model_type_was = owner.attribute_before_last_save(reflection.foreign_type)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      model_was = owner.class.polymorphic_class_for(model_type_was) if model_type_was
         
     | 
| 
       59 
65 
     | 
    
         
             
                    else
         
     | 
| 
       60 
66 
     | 
    
         
             
                      model_was = klass
         
     | 
| 
       61 
67 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -68,6 +74,14 @@ module ActiveRecord 
     | 
|
| 
       68 
74 
     | 
    
         
             
                  end
         
     | 
| 
       69 
75 
     | 
    
         | 
| 
       70 
76 
     | 
    
         
             
                  def target_changed?
         
     | 
| 
      
 77 
     | 
    
         
            +
                    owner.attribute_changed?(reflection.foreign_key) || (!foreign_key_present? && target&.new_record?)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  def target_previously_changed?
         
     | 
| 
      
 81 
     | 
    
         
            +
                    owner.attribute_previously_changed?(reflection.foreign_key)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def saved_change_to_target?
         
     | 
| 
       71 
85 
     | 
    
         
             
                    owner.saved_change_to_attribute?(reflection.foreign_key)
         
     | 
| 
       72 
86 
     | 
    
         
             
                  end
         
     | 
| 
       73 
87 
     | 
    
         | 
| 
         @@ -77,6 +91,8 @@ module ActiveRecord 
     | 
|
| 
       77 
91 
     | 
    
         
             
                        raise_on_type_mismatch!(record)
         
     | 
| 
       78 
92 
     | 
    
         
             
                        set_inverse_instance(record)
         
     | 
| 
       79 
93 
     | 
    
         
             
                        @updated = true
         
     | 
| 
      
 94 
     | 
    
         
            +
                      elsif target
         
     | 
| 
      
 95 
     | 
    
         
            +
                        remove_inverse_instance(target)
         
     | 
| 
       80 
96 
     | 
    
         
             
                      end
         
     | 
| 
       81 
97 
     | 
    
         | 
| 
       82 
98 
     | 
    
         
             
                      replace_keys(record, force: true)
         
     | 
| 
         @@ -108,10 +124,13 @@ module ActiveRecord 
     | 
|
| 
       108 
124 
     | 
    
         
             
                    end
         
     | 
| 
       109 
125 
     | 
    
         | 
| 
       110 
126 
     | 
    
         
             
                    def replace_keys(record, force: false)
         
     | 
| 
       111 
     | 
    
         
            -
                       
     | 
| 
      
 127 
     | 
    
         
            +
                      target_key_values = record ? Array(primary_key(record.class)).map { |key| record._read_attribute(key) } : []
         
     | 
| 
      
 128 
     | 
    
         
            +
                      reflection_fk = Array(reflection.foreign_key)
         
     | 
| 
       112 
129 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
                      if force || owner 
     | 
| 
       114 
     | 
    
         
            -
                         
     | 
| 
      
 130 
     | 
    
         
            +
                      if force || reflection_fk.map { |fk| owner._read_attribute(fk) } != target_key_values
         
     | 
| 
      
 131 
     | 
    
         
            +
                        reflection_fk.zip(target_key_values).each do |key, value|
         
     | 
| 
      
 132 
     | 
    
         
            +
                          owner[key] = value
         
     | 
| 
      
 133 
     | 
    
         
            +
                        end
         
     | 
| 
       115 
134 
     | 
    
         
             
                      end
         
     | 
| 
       116 
135 
     | 
    
         
             
                    end
         
     | 
| 
       117 
136 
     | 
    
         | 
| 
         @@ -120,12 +139,12 @@ module ActiveRecord 
     | 
|
| 
       120 
139 
     | 
    
         
             
                    end
         
     | 
| 
       121 
140 
     | 
    
         | 
| 
       122 
141 
     | 
    
         
             
                    def foreign_key_present?
         
     | 
| 
       123 
     | 
    
         
            -
                       
     | 
| 
      
 142 
     | 
    
         
            +
                      Array(reflection.foreign_key).all? { |fk| owner._read_attribute(fk) }
         
     | 
| 
       124 
143 
     | 
    
         
             
                    end
         
     | 
| 
       125 
144 
     | 
    
         | 
| 
       126 
145 
     | 
    
         
             
                    def invertible_for?(record)
         
     | 
| 
       127 
146 
     | 
    
         
             
                      inverse = inverse_reflection_for(record)
         
     | 
| 
       128 
     | 
    
         
            -
                      inverse && (inverse.has_one? ||  
     | 
| 
      
 147 
     | 
    
         
            +
                      inverse && (inverse.has_one? || inverse.klass.has_many_inversing)
         
     | 
| 
       129 
148 
     | 
    
         
             
                    end
         
     | 
| 
       130 
149 
     | 
    
         | 
| 
       131 
150 
     | 
    
         
             
                    def stale_state
         
     | 
| 
         @@ -3,13 +3,21 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Associations
         
     | 
| 
       5 
5 
     | 
    
         
             
                # = Active Record Belongs To Polymorphic Association
         
     | 
| 
       6 
     | 
    
         
            -
                class BelongsToPolymorphicAssociation < BelongsToAssociation  
     | 
| 
      
 6 
     | 
    
         
            +
                class BelongsToPolymorphicAssociation < BelongsToAssociation # :nodoc:
         
     | 
| 
       7 
7 
     | 
    
         
             
                  def klass
         
     | 
| 
       8 
8 
     | 
    
         
             
                    type = owner[reflection.foreign_type]
         
     | 
| 
       9 
9 
     | 
    
         
             
                    type.presence && owner.class.polymorphic_class_for(type)
         
     | 
| 
       10 
10 
     | 
    
         
             
                  end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                  def target_changed?
         
     | 
| 
      
 13 
     | 
    
         
            +
                    super || owner.attribute_changed?(reflection.foreign_type)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def target_previously_changed?
         
     | 
| 
      
 17 
     | 
    
         
            +
                    super || owner.attribute_previously_changed?(reflection.foreign_type)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def saved_change_to_target?
         
     | 
| 
       13 
21 
     | 
    
         
             
                    super || owner.saved_change_to_attribute?(reflection.foreign_type)
         
     | 
| 
       14 
22 
     | 
    
         
             
                  end
         
     | 
| 
       15 
23 
     | 
    
         | 
| 
         @@ -19,7 +27,7 @@ module ActiveRecord 
     | 
|
| 
       19 
27 
     | 
    
         | 
| 
       20 
28 
     | 
    
         
             
                      target_type = record ? record.class.polymorphic_name : nil
         
     | 
| 
       21 
29 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                      if force || owner 
     | 
| 
      
 30 
     | 
    
         
            +
                      if force || owner._read_attribute(reflection.foreign_type) != target_type
         
     | 
| 
       23 
31 
     | 
    
         
             
                        owner[reflection.foreign_type] = target_type
         
     | 
| 
       24 
32 
     | 
    
         
             
                      end
         
     | 
| 
       25 
33 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -12,14 +12,14 @@ 
     | 
|
| 
       12 
12 
     | 
    
         
             
            #      - HasManyAssociation
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
            module ActiveRecord::Associations::Builder # :nodoc:
         
     | 
| 
       15 
     | 
    
         
            -
              class Association  
     | 
| 
      
 15 
     | 
    
         
            +
              class Association # :nodoc:
         
     | 
| 
       16 
16 
     | 
    
         
             
                class << self
         
     | 
| 
       17 
17 
     | 
    
         
             
                  attr_accessor :extensions
         
     | 
| 
       18 
18 
     | 
    
         
             
                end
         
     | 
| 
       19 
19 
     | 
    
         
             
                self.extensions = []
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                VALID_OPTIONS = [
         
     | 
| 
       22 
     | 
    
         
            -
                  :class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading
         
     | 
| 
      
 22 
     | 
    
         
            +
                  :class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading, :query_constraints
         
     | 
| 
       23 
23 
     | 
    
         
             
                ].freeze # :nodoc:
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                def self.build(model, name, scope, options, &block)
         
     | 
| 
         @@ -33,6 +33,7 @@ module ActiveRecord::Associations::Builder # :nodoc: 
     | 
|
| 
       33 
33 
     | 
    
         
             
                  define_accessors model, reflection
         
     | 
| 
       34 
34 
     | 
    
         
             
                  define_callbacks model, reflection
         
     | 
| 
       35 
35 
     | 
    
         
             
                  define_validations model, reflection
         
     | 
| 
      
 36 
     | 
    
         
            +
                  define_change_tracking_methods model, reflection
         
     | 
| 
       36 
37 
     | 
    
         
             
                  reflection
         
     | 
| 
       37 
38 
     | 
    
         
             
                end
         
     | 
| 
       38 
39 
     | 
    
         | 
| 
         @@ -117,14 +118,18 @@ module ActiveRecord::Associations::Builder # :nodoc: 
     | 
|
| 
       117 
118 
     | 
    
         
             
                  # noop
         
     | 
| 
       118 
119 
     | 
    
         
             
                end
         
     | 
| 
       119 
120 
     | 
    
         | 
| 
      
 121 
     | 
    
         
            +
                def self.define_change_tracking_methods(model, reflection)
         
     | 
| 
      
 122 
     | 
    
         
            +
                  # noop
         
     | 
| 
      
 123 
     | 
    
         
            +
                end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
       120 
125 
     | 
    
         
             
                def self.valid_dependent_options
         
     | 
| 
       121 
126 
     | 
    
         
             
                  raise NotImplementedError
         
     | 
| 
       122 
127 
     | 
    
         
             
                end
         
     | 
| 
       123 
128 
     | 
    
         | 
| 
       124 
129 
     | 
    
         
             
                def self.check_dependent_options(dependent, model)
         
     | 
| 
       125 
130 
     | 
    
         
             
                  if dependent == :destroy_async && !model.destroy_association_async_job
         
     | 
| 
       126 
     | 
    
         
            -
                    err_message = " 
     | 
| 
       127 
     | 
    
         
            -
                    raise ActiveRecord:: 
     | 
| 
      
 131 
     | 
    
         
            +
                    err_message = "A valid destroy_association_async_job is required to use `dependent: :destroy_async` on associations"
         
     | 
| 
      
 132 
     | 
    
         
            +
                    raise ActiveRecord::ConfigurationError, err_message
         
     | 
| 
       128 
133 
     | 
    
         
             
                  end
         
     | 
| 
       129 
134 
     | 
    
         
             
                  unless valid_dependent_options.include? dependent
         
     | 
| 
       130 
135 
     | 
    
         
             
                    raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}"
         
     | 
| 
         @@ -158,6 +163,7 @@ module ActiveRecord::Associations::Builder # :nodoc: 
     | 
|
| 
       158 
163 
     | 
    
         | 
| 
       159 
164 
     | 
    
         
             
                private_class_method :build_scope, :macro, :valid_options, :validate_options, :define_extensions,
         
     | 
| 
       160 
165 
     | 
    
         
             
                  :define_callbacks, :define_accessors, :define_readers, :define_writers, :define_validations,
         
     | 
| 
       161 
     | 
    
         
            -
                  : 
     | 
| 
      
 166 
     | 
    
         
            +
                  :define_change_tracking_methods, :valid_dependent_options, :check_dependent_options,
         
     | 
| 
      
 167 
     | 
    
         
            +
                  :add_destroy_callbacks, :add_after_commit_jobs_callback
         
     | 
| 
       162 
168 
     | 
    
         
             
              end
         
     | 
| 
       163 
169 
     | 
    
         
             
            end
         
     |