activerecord 5.2.8 → 7.0.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 +1393 -587
 - data/MIT-LICENSE +3 -1
 - data/README.rdoc +7 -5
 - data/examples/performance.rb +1 -1
 - data/lib/active_record/aggregations.rb +10 -9
 - data/lib/active_record/association_relation.rb +22 -12
 - data/lib/active_record/associations/alias_tracker.rb +19 -16
 - data/lib/active_record/associations/association.rb +122 -47
 - data/lib/active_record/associations/association_scope.rb +24 -24
 - data/lib/active_record/associations/belongs_to_association.rb +67 -49
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -7
 - data/lib/active_record/associations/builder/association.rb +52 -23
 - data/lib/active_record/associations/builder/belongs_to.rb +44 -61
 - data/lib/active_record/associations/builder/collection_association.rb +17 -19
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
 - data/lib/active_record/associations/builder/has_many.rb +10 -3
 - data/lib/active_record/associations/builder/has_one.rb +35 -3
 - data/lib/active_record/associations/builder/singular_association.rb +5 -3
 - data/lib/active_record/associations/collection_association.rb +59 -50
 - data/lib/active_record/associations/collection_proxy.rb +32 -23
 - data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
 - data/lib/active_record/associations/foreign_association.rb +20 -0
 - data/lib/active_record/associations/has_many_association.rb +27 -14
 - data/lib/active_record/associations/has_many_through_association.rb +26 -19
 - data/lib/active_record/associations/has_one_association.rb +52 -37
 - data/lib/active_record/associations/has_one_through_association.rb +6 -6
 - data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
 - data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
 - data/lib/active_record/associations/join_dependency.rb +97 -62
 - data/lib/active_record/associations/preloader/association.rb +220 -60
 - 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 +85 -40
 - data/lib/active_record/associations/preloader.rb +44 -105
 - data/lib/active_record/associations/singular_association.rb +9 -17
 - data/lib/active_record/associations/through_association.rb +4 -4
 - data/lib/active_record/associations.rb +207 -66
 - data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
 - data/lib/active_record/attribute_assignment.rb +17 -19
 - data/lib/active_record/attribute_methods/before_type_cast.rb +19 -8
 - data/lib/active_record/attribute_methods/dirty.rb +141 -47
 - data/lib/active_record/attribute_methods/primary_key.rb +22 -27
 - data/lib/active_record/attribute_methods/query.rb +6 -10
 - data/lib/active_record/attribute_methods/read.rb +15 -55
 - data/lib/active_record/attribute_methods/serialization.rb +77 -18
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +16 -18
 - data/lib/active_record/attribute_methods/write.rb +18 -37
 - data/lib/active_record/attribute_methods.rb +90 -153
 - data/lib/active_record/attributes.rb +38 -12
 - data/lib/active_record/autosave_association.rb +50 -50
 - data/lib/active_record/base.rb +23 -18
 - data/lib/active_record/callbacks.rb +159 -44
 - data/lib/active_record/coders/yaml_column.rb +12 -3
 - data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +92 -464
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -51
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +209 -164
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +38 -22
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +103 -82
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +140 -110
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -94
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +16 -5
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +456 -159
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -162
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +311 -327
 - data/lib/active_record/connection_adapters/column.rb +33 -11
 - data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
 - data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
 - data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +113 -45
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +71 -5
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +25 -8
 - data/lib/active_record/connection_adapters/mysql/schema_statements.rb +143 -19
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +63 -22
 - data/lib/active_record/connection_adapters/pool_config.rb +73 -0
 - data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
 - data/lib/active_record/connection_adapters/postgresql/column.rb +53 -28
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +56 -63
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +54 -16
 - data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
 - data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
 - 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 +26 -12
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -52
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -2
 - data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +39 -4
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +128 -91
 - data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -1
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +149 -113
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +386 -182
 - data/lib/active_record/connection_adapters/schema_cache.rb +161 -22
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
 - data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +152 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +65 -18
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
 - data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +92 -26
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +251 -204
 - data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
 - data/lib/active_record/connection_adapters.rb +53 -0
 - data/lib/active_record/connection_handling.rb +292 -38
 - data/lib/active_record/core.rb +385 -158
 - data/lib/active_record/counter_cache.rb +8 -30
 - data/lib/active_record/database_configurations/connection_url_resolver.rb +100 -0
 - data/lib/active_record/database_configurations/database_config.rb +83 -0
 - data/lib/active_record/database_configurations/hash_config.rb +154 -0
 - data/lib/active_record/database_configurations/url_config.rb +53 -0
 - data/lib/active_record/database_configurations.rb +256 -0
 - data/lib/active_record/delegated_type.rb +250 -0
 - data/lib/active_record/destroy_association_async_job.rb +36 -0
 - data/lib/active_record/disable_joins_association_relation.rb +39 -0
 - data/lib/active_record/dynamic_matchers.rb +4 -5
 - data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
 - data/lib/active_record/encryption/cipher.rb +53 -0
 - data/lib/active_record/encryption/config.rb +44 -0
 - data/lib/active_record/encryption/configurable.rb +61 -0
 - data/lib/active_record/encryption/context.rb +35 -0
 - data/lib/active_record/encryption/contexts.rb +72 -0
 - data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
 - data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
 - data/lib/active_record/encryption/encryptable_record.rb +208 -0
 - data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -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 +160 -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 +42 -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 +90 -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 +99 -0
 - data/lib/active_record/encryption.rb +55 -0
 - data/lib/active_record/enum.rb +130 -51
 - data/lib/active_record/errors.rb +129 -23
 - data/lib/active_record/explain.rb +10 -6
 - 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 +22 -15
 - data/lib/active_record/fixture_set/model_metadata.rb +32 -0
 - data/lib/active_record/fixture_set/render_context.rb +17 -0
 - data/lib/active_record/fixture_set/table_row.rb +187 -0
 - data/lib/active_record/fixture_set/table_rows.rb +46 -0
 - data/lib/active_record/fixtures.rb +206 -490
 - data/lib/active_record/future_result.rb +139 -0
 - data/lib/active_record/gem_version.rb +3 -3
 - data/lib/active_record/inheritance.rb +104 -37
 - data/lib/active_record/insert_all.rb +278 -0
 - data/lib/active_record/integration.rb +69 -18
 - data/lib/active_record/internal_metadata.rb +24 -9
 - data/lib/active_record/legacy_yaml_adapter.rb +3 -36
 - data/lib/active_record/locking/optimistic.rb +41 -26
 - data/lib/active_record/locking/pessimistic.rb +18 -8
 - data/lib/active_record/log_subscriber.rb +46 -35
 - data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
 - data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
 - data/lib/active_record/middleware/database_selector.rb +82 -0
 - data/lib/active_record/middleware/shard_selector.rb +60 -0
 - data/lib/active_record/migration/command_recorder.rb +96 -44
 - data/lib/active_record/migration/compatibility.rb +246 -64
 - data/lib/active_record/migration/join_table.rb +1 -2
 - data/lib/active_record/migration.rb +266 -187
 - data/lib/active_record/model_schema.rb +165 -52
 - data/lib/active_record/nested_attributes.rb +17 -19
 - data/lib/active_record/no_touching.rb +11 -4
 - data/lib/active_record/null_relation.rb +2 -7
 - data/lib/active_record/persistence.rb +467 -92
 - data/lib/active_record/query_cache.rb +21 -4
 - data/lib/active_record/query_logs.rb +138 -0
 - data/lib/active_record/querying.rb +51 -24
 - data/lib/active_record/railtie.rb +224 -57
 - data/lib/active_record/railties/console_sandbox.rb +2 -4
 - data/lib/active_record/railties/controller_runtime.rb +31 -36
 - data/lib/active_record/railties/databases.rake +369 -101
 - data/lib/active_record/readonly_attributes.rb +15 -0
 - data/lib/active_record/reflection.rb +170 -137
 - data/lib/active_record/relation/batches/batch_enumerator.rb +44 -14
 - data/lib/active_record/relation/batches.rb +46 -37
 - data/lib/active_record/relation/calculations.rb +168 -96
 - data/lib/active_record/relation/delegation.rb +37 -52
 - data/lib/active_record/relation/finder_methods.rb +79 -58
 - data/lib/active_record/relation/from_clause.rb +5 -1
 - data/lib/active_record/relation/merger.rb +50 -51
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
 - data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
 - data/lib/active_record/relation/predicate_builder.rb +58 -46
 - data/lib/active_record/relation/query_attribute.rb +9 -10
 - data/lib/active_record/relation/query_methods.rb +685 -208
 - data/lib/active_record/relation/record_fetch_warning.rb +9 -11
 - data/lib/active_record/relation/spawn_methods.rb +10 -10
 - data/lib/active_record/relation/where_clause.rb +108 -64
 - data/lib/active_record/relation.rb +515 -151
 - data/lib/active_record/result.rb +78 -42
 - data/lib/active_record/runtime_registry.rb +9 -13
 - data/lib/active_record/sanitization.rb +29 -44
 - data/lib/active_record/schema.rb +37 -31
 - data/lib/active_record/schema_dumper.rb +74 -23
 - data/lib/active_record/schema_migration.rb +7 -9
 - data/lib/active_record/scoping/default.rb +62 -17
 - data/lib/active_record/scoping/named.rb +17 -32
 - data/lib/active_record/scoping.rb +70 -41
 - data/lib/active_record/secure_token.rb +16 -8
 - data/lib/active_record/serialization.rb +6 -4
 - data/lib/active_record/signed_id.rb +116 -0
 - data/lib/active_record/statement_cache.rb +49 -6
 - data/lib/active_record/store.rb +88 -9
 - data/lib/active_record/suppressor.rb +13 -17
 - data/lib/active_record/table_metadata.rb +42 -43
 - data/lib/active_record/tasks/database_tasks.rb +352 -94
 - data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +41 -39
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
 - data/lib/active_record/test_databases.rb +24 -0
 - data/lib/active_record/test_fixtures.rb +287 -0
 - data/lib/active_record/timestamp.rb +44 -34
 - data/lib/active_record/touch_later.rb +23 -22
 - data/lib/active_record/transactions.rb +67 -128
 - data/lib/active_record/translation.rb +3 -3
 - data/lib/active_record/type/adapter_specific_registry.rb +34 -19
 - data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
 - data/lib/active_record/type/internal/timezone.rb +2 -2
 - data/lib/active_record/type/serialized.rb +7 -4
 - data/lib/active_record/type/time.rb +10 -0
 - data/lib/active_record/type/type_map.rb +17 -21
 - data/lib/active_record/type/unsigned_integer.rb +0 -1
 - data/lib/active_record/type.rb +9 -5
 - data/lib/active_record/type_caster/connection.rb +15 -15
 - data/lib/active_record/type_caster/map.rb +8 -8
 - data/lib/active_record/validations/associated.rb +2 -3
 - data/lib/active_record/validations/numericality.rb +35 -0
 - data/lib/active_record/validations/uniqueness.rb +39 -31
 - data/lib/active_record/validations.rb +4 -3
 - data/lib/active_record.rb +209 -32
 - data/lib/arel/alias_predication.rb +9 -0
 - data/lib/arel/attributes/attribute.rb +33 -0
 - data/lib/arel/collectors/bind.rb +29 -0
 - data/lib/arel/collectors/composite.rb +39 -0
 - data/lib/arel/collectors/plain_string.rb +20 -0
 - data/lib/arel/collectors/sql_string.rb +27 -0
 - data/lib/arel/collectors/substitute_binds.rb +35 -0
 - data/lib/arel/crud.rb +48 -0
 - data/lib/arel/delete_manager.rb +32 -0
 - data/lib/arel/errors.rb +9 -0
 - data/lib/arel/expressions.rb +29 -0
 - data/lib/arel/factory_methods.rb +49 -0
 - data/lib/arel/filter_predications.rb +9 -0
 - data/lib/arel/insert_manager.rb +48 -0
 - data/lib/arel/math.rb +45 -0
 - data/lib/arel/nodes/and.rb +32 -0
 - data/lib/arel/nodes/ascending.rb +23 -0
 - data/lib/arel/nodes/binary.rb +126 -0
 - data/lib/arel/nodes/bind_param.rb +44 -0
 - data/lib/arel/nodes/case.rb +55 -0
 - data/lib/arel/nodes/casted.rb +62 -0
 - data/lib/arel/nodes/comment.rb +29 -0
 - data/lib/arel/nodes/count.rb +12 -0
 - data/lib/arel/nodes/delete_statement.rb +44 -0
 - data/lib/arel/nodes/descending.rb +23 -0
 - data/lib/arel/nodes/equality.rb +15 -0
 - data/lib/arel/nodes/extract.rb +24 -0
 - data/lib/arel/nodes/false.rb +16 -0
 - data/lib/arel/nodes/filter.rb +10 -0
 - data/lib/arel/nodes/full_outer_join.rb +8 -0
 - data/lib/arel/nodes/function.rb +45 -0
 - data/lib/arel/nodes/grouping.rb +11 -0
 - data/lib/arel/nodes/homogeneous_in.rb +76 -0
 - data/lib/arel/nodes/in.rb +15 -0
 - data/lib/arel/nodes/infix_operation.rb +92 -0
 - data/lib/arel/nodes/inner_join.rb +8 -0
 - data/lib/arel/nodes/insert_statement.rb +37 -0
 - data/lib/arel/nodes/join_source.rb +20 -0
 - data/lib/arel/nodes/matches.rb +18 -0
 - data/lib/arel/nodes/named_function.rb +23 -0
 - data/lib/arel/nodes/node.rb +51 -0
 - data/lib/arel/nodes/node_expression.rb +13 -0
 - data/lib/arel/nodes/ordering.rb +27 -0
 - data/lib/arel/nodes/outer_join.rb +8 -0
 - data/lib/arel/nodes/over.rb +15 -0
 - data/lib/arel/nodes/regexp.rb +16 -0
 - data/lib/arel/nodes/right_outer_join.rb +8 -0
 - data/lib/arel/nodes/select_core.rb +67 -0
 - data/lib/arel/nodes/select_statement.rb +41 -0
 - data/lib/arel/nodes/sql_literal.rb +19 -0
 - data/lib/arel/nodes/string_join.rb +11 -0
 - data/lib/arel/nodes/table_alias.rb +31 -0
 - data/lib/arel/nodes/terminal.rb +16 -0
 - data/lib/arel/nodes/true.rb +16 -0
 - data/lib/arel/nodes/unary.rb +44 -0
 - data/lib/arel/nodes/unary_operation.rb +20 -0
 - data/lib/arel/nodes/unqualified_column.rb +22 -0
 - data/lib/arel/nodes/update_statement.rb +46 -0
 - data/lib/arel/nodes/values_list.rb +9 -0
 - data/lib/arel/nodes/window.rb +126 -0
 - data/lib/arel/nodes/with.rb +11 -0
 - data/lib/arel/nodes.rb +71 -0
 - data/lib/arel/order_predications.rb +13 -0
 - data/lib/arel/predications.rb +258 -0
 - data/lib/arel/select_manager.rb +276 -0
 - data/lib/arel/table.rb +117 -0
 - data/lib/arel/tree_manager.rb +60 -0
 - data/lib/arel/update_manager.rb +48 -0
 - data/lib/arel/visitors/dot.rb +298 -0
 - data/lib/arel/visitors/mysql.rb +99 -0
 - data/lib/arel/visitors/postgresql.rb +110 -0
 - data/lib/arel/visitors/sqlite.rb +38 -0
 - data/lib/arel/visitors/to_sql.rb +955 -0
 - data/lib/arel/visitors/visitor.rb +45 -0
 - data/lib/arel/visitors.rb +13 -0
 - data/lib/arel/window_predications.rb +9 -0
 - data/lib/arel.rb +55 -0
 - data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
 - data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
 - data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
 - data/lib/rails/generators/active_record/migration.rb +19 -2
 - data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
 - data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
 - data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -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 +162 -32
 - data/lib/active_record/attribute_decorators.rb +0 -90
 - data/lib/active_record/collection_cache_key.rb +0 -53
 - data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
 - data/lib/active_record/define_callbacks.rb +0 -22
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
 - data/lib/active_record/relation/where_clause_factory.rb +0 -34
 
| 
         @@ -1,42 +1,107 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require "active_support/core_ext/enumerable"
         
     | 
| 
       4 
     | 
    
         
            -
            require "active_support/core_ext/string/conversions"
         
     | 
| 
       5 
     | 
    
         
            -
            require "active_support/core_ext/module/remove_method"
         
     | 
| 
       6 
     | 
    
         
            -
            require "active_record/errors"
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       9 
     | 
    
         
            -
              class AssociationNotFoundError < ConfigurationError  
     | 
| 
      
 4 
     | 
    
         
            +
              class AssociationNotFoundError < ConfigurationError # :nodoc:
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :record, :association_name
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       10 
7 
     | 
    
         
             
                def initialize(record = nil, association_name = nil)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @record           = record
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @association_name = association_name
         
     | 
| 
       11 
10 
     | 
    
         
             
                  if record && association_name
         
     | 
| 
       12 
11 
     | 
    
         
             
                    super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
         
     | 
| 
       13 
12 
     | 
    
         
             
                  else
         
     | 
| 
       14 
13 
     | 
    
         
             
                    super("Association was not found.")
         
     | 
| 
       15 
14 
     | 
    
         
             
                  end
         
     | 
| 
       16 
15 
     | 
    
         
             
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  include DidYouMean::Correctable
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def corrections
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if record && association_name
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @corrections ||= begin
         
     | 
| 
      
 23 
     | 
    
         
            +
                        maybe_these = record.class.reflections.keys
         
     | 
| 
      
 24 
     | 
    
         
            +
                        DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(association_name)
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
      
 26 
     | 
    
         
            +
                    else
         
     | 
| 
      
 27 
     | 
    
         
            +
                      []
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
       17 
31 
     | 
    
         
             
              end
         
     | 
| 
       18 
32 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
              class InverseOfAssociationNotFoundError < ActiveRecordError  
     | 
| 
      
 33 
     | 
    
         
            +
              class InverseOfAssociationNotFoundError < ActiveRecordError # :nodoc:
         
     | 
| 
      
 34 
     | 
    
         
            +
                attr_reader :reflection, :associated_class
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
       20 
36 
     | 
    
         
             
                def initialize(reflection = nil, associated_class = nil)
         
     | 
| 
       21 
37 
     | 
    
         
             
                  if reflection
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @reflection = reflection
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @associated_class = associated_class.nil? ? reflection.klass : associated_class
         
     | 
| 
       22 
40 
     | 
    
         
             
                    super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
         
     | 
| 
       23 
41 
     | 
    
         
             
                  else
         
     | 
| 
       24 
42 
     | 
    
         
             
                    super("Could not find the inverse association.")
         
     | 
| 
       25 
43 
     | 
    
         
             
                  end
         
     | 
| 
       26 
44 
     | 
    
         
             
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  include DidYouMean::Correctable
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def corrections
         
     | 
| 
      
 50 
     | 
    
         
            +
                    if reflection && associated_class
         
     | 
| 
      
 51 
     | 
    
         
            +
                      @corrections ||= begin
         
     | 
| 
      
 52 
     | 
    
         
            +
                        maybe_these = associated_class.reflections.keys
         
     | 
| 
      
 53 
     | 
    
         
            +
                        DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(reflection.options[:inverse_of].to_s)
         
     | 
| 
      
 54 
     | 
    
         
            +
                      end
         
     | 
| 
      
 55 
     | 
    
         
            +
                    else
         
     | 
| 
      
 56 
     | 
    
         
            +
                      []
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
       27 
60 
     | 
    
         
             
              end
         
     | 
| 
       28 
61 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
              class  
     | 
| 
       30 
     | 
    
         
            -
                 
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
      
 62 
     | 
    
         
            +
              class InverseOfAssociationRecursiveError < ActiveRecordError # :nodoc:
         
     | 
| 
      
 63 
     | 
    
         
            +
                attr_reader :reflection
         
     | 
| 
      
 64 
     | 
    
         
            +
                def initialize(reflection = nil)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  if reflection
         
     | 
| 
      
 66 
     | 
    
         
            +
                    @reflection = reflection
         
     | 
| 
      
 67 
     | 
    
         
            +
                    super("Inverse association #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{reflection.class_name}) is recursive.")
         
     | 
| 
      
 68 
     | 
    
         
            +
                  else
         
     | 
| 
      
 69 
     | 
    
         
            +
                    super("Inverse association is recursive.")
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              class HasManyThroughAssociationNotFoundError < ActiveRecordError # :nodoc:
         
     | 
| 
      
 75 
     | 
    
         
            +
                attr_reader :owner_class, :reflection
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                def initialize(owner_class = nil, reflection = nil)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  if owner_class && reflection
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @owner_class = owner_class
         
     | 
| 
      
 80 
     | 
    
         
            +
                    @reflection = reflection
         
     | 
| 
      
 81 
     | 
    
         
            +
                    super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class.name}")
         
     | 
| 
       33 
82 
     | 
    
         
             
                  else
         
     | 
| 
       34 
83 
     | 
    
         
             
                    super("Could not find the association.")
         
     | 
| 
       35 
84 
     | 
    
         
             
                  end
         
     | 
| 
       36 
85 
     | 
    
         
             
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  include DidYouMean::Correctable
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  def corrections
         
     | 
| 
      
 91 
     | 
    
         
            +
                    if owner_class && reflection
         
     | 
| 
      
 92 
     | 
    
         
            +
                      @corrections ||= begin
         
     | 
| 
      
 93 
     | 
    
         
            +
                        maybe_these = owner_class.reflections.keys
         
     | 
| 
      
 94 
     | 
    
         
            +
                        maybe_these -= [reflection.name.to_s] # remove failing reflection
         
     | 
| 
      
 95 
     | 
    
         
            +
                        DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(reflection.options[:through].to_s)
         
     | 
| 
      
 96 
     | 
    
         
            +
                      end
         
     | 
| 
      
 97 
     | 
    
         
            +
                    else
         
     | 
| 
      
 98 
     | 
    
         
            +
                      []
         
     | 
| 
      
 99 
     | 
    
         
            +
                    end
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
       37 
102 
     | 
    
         
             
              end
         
     | 
| 
       38 
103 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
              class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError  
     | 
| 
      
 104 
     | 
    
         
            +
              class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError # :nodoc:
         
     | 
| 
       40 
105 
     | 
    
         
             
                def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
         
     | 
| 
       41 
106 
     | 
    
         
             
                  if owner_class_name && reflection && source_reflection
         
     | 
| 
       42 
107 
     | 
    
         
             
                    super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
         
     | 
| 
         @@ -46,7 +111,7 @@ module ActiveRecord 
     | 
|
| 
       46 
111 
     | 
    
         
             
                end
         
     | 
| 
       47 
112 
     | 
    
         
             
              end
         
     | 
| 
       48 
113 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
              class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError  
     | 
| 
      
 114 
     | 
    
         
            +
              class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError # :nodoc:
         
     | 
| 
       50 
115 
     | 
    
         
             
                def initialize(owner_class_name = nil, reflection = nil)
         
     | 
| 
       51 
116 
     | 
    
         
             
                  if owner_class_name && reflection
         
     | 
| 
       52 
117 
     | 
    
         
             
                    super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
         
     | 
| 
         @@ -56,7 +121,7 @@ module ActiveRecord 
     | 
|
| 
       56 
121 
     | 
    
         
             
                end
         
     | 
| 
       57 
122 
     | 
    
         
             
              end
         
     | 
| 
       58 
123 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
              class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError  
     | 
| 
      
 124 
     | 
    
         
            +
              class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError # :nodoc:
         
     | 
| 
       60 
125 
     | 
    
         
             
                def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
         
     | 
| 
       61 
126 
     | 
    
         
             
                  if owner_class_name && reflection && source_reflection
         
     | 
| 
       62 
127 
     | 
    
         
             
                    super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
         
     | 
| 
         @@ -66,7 +131,7 @@ module ActiveRecord 
     | 
|
| 
       66 
131 
     | 
    
         
             
                end
         
     | 
| 
       67 
132 
     | 
    
         
             
              end
         
     | 
| 
       68 
133 
     | 
    
         | 
| 
       69 
     | 
    
         
            -
              class HasOneThroughCantAssociateThroughCollection < ActiveRecordError  
     | 
| 
      
 134 
     | 
    
         
            +
              class HasOneThroughCantAssociateThroughCollection < ActiveRecordError # :nodoc:
         
     | 
| 
       70 
135 
     | 
    
         
             
                def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
         
     | 
| 
       71 
136 
     | 
    
         
             
                  if owner_class_name && reflection && through_reflection
         
     | 
| 
       72 
137 
     | 
    
         
             
                    super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
         
     | 
| 
         @@ -76,7 +141,7 @@ module ActiveRecord 
     | 
|
| 
       76 
141 
     | 
    
         
             
                end
         
     | 
| 
       77 
142 
     | 
    
         
             
              end
         
     | 
| 
       78 
143 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
              class HasOneAssociationPolymorphicThroughError < ActiveRecordError  
     | 
| 
      
 144 
     | 
    
         
            +
              class HasOneAssociationPolymorphicThroughError < ActiveRecordError # :nodoc:
         
     | 
| 
       80 
145 
     | 
    
         
             
                def initialize(owner_class_name = nil, reflection = nil)
         
     | 
| 
       81 
146 
     | 
    
         
             
                  if owner_class_name && reflection
         
     | 
| 
       82 
147 
     | 
    
         
             
                    super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
         
     | 
| 
         @@ -86,20 +151,20 @@ module ActiveRecord 
     | 
|
| 
       86 
151 
     | 
    
         
             
                end
         
     | 
| 
       87 
152 
     | 
    
         
             
              end
         
     | 
| 
       88 
153 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
              class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError  
     | 
| 
      
 154 
     | 
    
         
            +
              class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError # :nodoc:
         
     | 
| 
       90 
155 
     | 
    
         
             
                def initialize(reflection = nil)
         
     | 
| 
       91 
156 
     | 
    
         
             
                  if reflection
         
     | 
| 
       92 
157 
     | 
    
         
             
                    through_reflection      = reflection.through_reflection
         
     | 
| 
       93 
158 
     | 
    
         
             
                    source_reflection_names = reflection.source_reflection_names
         
     | 
| 
       94 
159 
     | 
    
         
             
                    source_associations     = reflection.through_reflection.klass._reflections.keys
         
     | 
| 
       95 
     | 
    
         
            -
                    super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ' 
     | 
| 
      
 160 
     | 
    
         
            +
                    super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')}?")
         
     | 
| 
       96 
161 
     | 
    
         
             
                  else
         
     | 
| 
       97 
162 
     | 
    
         
             
                    super("Could not find the source association(s).")
         
     | 
| 
       98 
163 
     | 
    
         
             
                  end
         
     | 
| 
       99 
164 
     | 
    
         
             
                end
         
     | 
| 
       100 
165 
     | 
    
         
             
              end
         
     | 
| 
       101 
166 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
              class HasManyThroughOrderError < ActiveRecordError  
     | 
| 
      
 167 
     | 
    
         
            +
              class HasManyThroughOrderError < ActiveRecordError # :nodoc:
         
     | 
| 
       103 
168 
     | 
    
         
             
                def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
         
     | 
| 
       104 
169 
     | 
    
         
             
                  if owner_class_name && reflection && through_reflection
         
     | 
| 
       105 
170 
     | 
    
         
             
                    super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through '#{owner_class_name}##{through_reflection.name}' before the through association is defined.")
         
     | 
| 
         @@ -109,7 +174,7 @@ module ActiveRecord 
     | 
|
| 
       109 
174 
     | 
    
         
             
                end
         
     | 
| 
       110 
175 
     | 
    
         
             
              end
         
     | 
| 
       111 
176 
     | 
    
         | 
| 
       112 
     | 
    
         
            -
              class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError  
     | 
| 
      
 177 
     | 
    
         
            +
              class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError # :nodoc:
         
     | 
| 
       113 
178 
     | 
    
         
             
                def initialize(owner = nil, reflection = nil)
         
     | 
| 
       114 
179 
     | 
    
         
             
                  if owner && reflection
         
     | 
| 
       115 
180 
     | 
    
         
             
                    super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
         
     | 
| 
         @@ -134,13 +199,13 @@ module ActiveRecord 
     | 
|
| 
       134 
199 
     | 
    
         
             
                end
         
     | 
| 
       135 
200 
     | 
    
         
             
              end
         
     | 
| 
       136 
201 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
              class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection  
     | 
| 
      
 202 
     | 
    
         
            +
              class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection # :nodoc:
         
     | 
| 
       138 
203 
     | 
    
         
             
              end
         
     | 
| 
       139 
204 
     | 
    
         | 
| 
       140 
     | 
    
         
            -
              class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection  
     | 
| 
      
 205 
     | 
    
         
            +
              class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection # :nodoc:
         
     | 
| 
       141 
206 
     | 
    
         
             
              end
         
     | 
| 
       142 
207 
     | 
    
         | 
| 
       143 
     | 
    
         
            -
              class ThroughNestedAssociationsAreReadonly < ActiveRecordError  
     | 
| 
      
 208 
     | 
    
         
            +
              class ThroughNestedAssociationsAreReadonly < ActiveRecordError # :nodoc:
         
     | 
| 
       144 
209 
     | 
    
         
             
                def initialize(owner = nil, reflection = nil)
         
     | 
| 
       145 
210 
     | 
    
         
             
                  if owner && reflection
         
     | 
| 
       146 
211 
     | 
    
         
             
                    super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
         
     | 
| 
         @@ -150,10 +215,10 @@ module ActiveRecord 
     | 
|
| 
       150 
215 
     | 
    
         
             
                end
         
     | 
| 
       151 
216 
     | 
    
         
             
              end
         
     | 
| 
       152 
217 
     | 
    
         | 
| 
       153 
     | 
    
         
            -
              class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly  
     | 
| 
      
 218 
     | 
    
         
            +
              class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly # :nodoc:
         
     | 
| 
       154 
219 
     | 
    
         
             
              end
         
     | 
| 
       155 
220 
     | 
    
         | 
| 
       156 
     | 
    
         
            -
              class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly  
     | 
| 
      
 221 
     | 
    
         
            +
              class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly # :nodoc:
         
     | 
| 
       157 
222 
     | 
    
         
             
              end
         
     | 
| 
       158 
223 
     | 
    
         | 
| 
       159 
224 
     | 
    
         
             
              # This error is raised when trying to eager load a polymorphic association using a JOIN.
         
     | 
| 
         @@ -172,7 +237,7 @@ module ActiveRecord 
     | 
|
| 
       172 
237 
     | 
    
         
             
              # This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
         
     | 
| 
       173 
238 
     | 
    
         
             
              # (has_many, has_one) when there is at least 1 child associated instance.
         
     | 
| 
       174 
239 
     | 
    
         
             
              # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
         
     | 
| 
       175 
     | 
    
         
            -
              class DeleteRestrictionError < ActiveRecordError  
     | 
| 
      
 240 
     | 
    
         
            +
              class DeleteRestrictionError < ActiveRecordError # :nodoc:
         
     | 
| 
       176 
241 
     | 
    
         
             
                def initialize(name = nil)
         
     | 
| 
       177 
242 
     | 
    
         
             
                  if name
         
     | 
| 
       178 
243 
     | 
    
         
             
                    super("Cannot delete record because of dependent #{name}")
         
     | 
| 
         @@ -196,7 +261,7 @@ module ActiveRecord 
     | 
|
| 
       196 
261 
     | 
    
         
             
                autoload :CollectionProxy
         
     | 
| 
       197 
262 
     | 
    
         
             
                autoload :ThroughAssociation
         
     | 
| 
       198 
263 
     | 
    
         | 
| 
       199 
     | 
    
         
            -
                module Builder  
     | 
| 
      
 264 
     | 
    
         
            +
                module Builder # :nodoc:
         
     | 
| 
       200 
265 
     | 
    
         
             
                  autoload :Association,           "active_record/associations/builder/association"
         
     | 
| 
       201 
266 
     | 
    
         
             
                  autoload :SingularAssociation,   "active_record/associations/builder/singular_association"
         
     | 
| 
       202 
267 
     | 
    
         
             
                  autoload :CollectionAssociation, "active_record/associations/builder/collection_association"
         
     | 
| 
         @@ -218,16 +283,18 @@ module ActiveRecord 
     | 
|
| 
       218 
283 
     | 
    
         
             
                  autoload :Preloader
         
     | 
| 
       219 
284 
     | 
    
         
             
                  autoload :JoinDependency
         
     | 
| 
       220 
285 
     | 
    
         
             
                  autoload :AssociationScope
         
     | 
| 
      
 286 
     | 
    
         
            +
                  autoload :DisableJoinsAssociationScope
         
     | 
| 
       221 
287 
     | 
    
         
             
                  autoload :AliasTracker
         
     | 
| 
       222 
288 
     | 
    
         
             
                end
         
     | 
| 
       223 
289 
     | 
    
         | 
| 
       224 
290 
     | 
    
         
             
                def self.eager_load!
         
     | 
| 
       225 
291 
     | 
    
         
             
                  super
         
     | 
| 
       226 
292 
     | 
    
         
             
                  Preloader.eager_load!
         
     | 
| 
      
 293 
     | 
    
         
            +
                  JoinDependency.eager_load!
         
     | 
| 
       227 
294 
     | 
    
         
             
                end
         
     | 
| 
       228 
295 
     | 
    
         | 
| 
       229 
296 
     | 
    
         
             
                # Returns the association instance for the given name, instantiating it if it doesn't already exist
         
     | 
| 
       230 
     | 
    
         
            -
                def association(name)  
     | 
| 
      
 297 
     | 
    
         
            +
                def association(name) # :nodoc:
         
     | 
| 
       231 
298 
     | 
    
         
             
                  association = association_instance_get(name)
         
     | 
| 
       232 
299 
     | 
    
         | 
| 
       233 
300 
     | 
    
         
             
                  if association.nil?
         
     | 
| 
         @@ -250,17 +317,7 @@ module ActiveRecord 
     | 
|
| 
       250 
317 
     | 
    
         
             
                  super
         
     | 
| 
       251 
318 
     | 
    
         
             
                end
         
     | 
| 
       252 
319 
     | 
    
         | 
| 
       253 
     | 
    
         
            -
                def reload(*) # :nodoc:
         
     | 
| 
       254 
     | 
    
         
            -
                  clear_association_cache
         
     | 
| 
       255 
     | 
    
         
            -
                  super
         
     | 
| 
       256 
     | 
    
         
            -
                end
         
     | 
| 
       257 
     | 
    
         
            -
             
     | 
| 
       258 
320 
     | 
    
         
             
                private
         
     | 
| 
       259 
     | 
    
         
            -
                  # Clears out the association cache.
         
     | 
| 
       260 
     | 
    
         
            -
                  def clear_association_cache
         
     | 
| 
       261 
     | 
    
         
            -
                    @association_cache.clear if persisted?
         
     | 
| 
       262 
     | 
    
         
            -
                  end
         
     | 
| 
       263 
     | 
    
         
            -
             
     | 
| 
       264 
321 
     | 
    
         
             
                  def init_internals
         
     | 
| 
       265 
322 
     | 
    
         
             
                    @association_cache = {}
         
     | 
| 
       266 
323 
     | 
    
         
             
                    super
         
     | 
| 
         @@ -292,13 +349,13 @@ module ActiveRecord 
     | 
|
| 
       292 
349 
     | 
    
         
             
                  #
         
     | 
| 
       293 
350 
     | 
    
         
             
                  # The project class now has the following methods (and more) to ease the traversal and
         
     | 
| 
       294 
351 
     | 
    
         
             
                  # manipulation of its relationships:
         
     | 
| 
       295 
     | 
    
         
            -
                  # * <tt>Project#portfolio 
     | 
| 
       296 
     | 
    
         
            -
                  # * <tt>Project#project_manager 
     | 
| 
       297 
     | 
    
         
            -
                  # * <tt>Project#milestones.empty 
     | 
| 
       298 
     | 
    
         
            -
                  #   <tt>Project#milestones.delete(milestone) 
     | 
| 
       299 
     | 
    
         
            -
                  #   <tt>Project#milestones.build 
     | 
| 
       300 
     | 
    
         
            -
                  # * <tt>Project#categories.empty 
     | 
| 
       301 
     | 
    
         
            -
                  #   <tt>Project#categories.delete(category1) 
     | 
| 
      
 352 
     | 
    
         
            +
                  # * <tt>Project#portfolio</tt>, <tt>Project#portfolio=(portfolio)</tt>, <tt>Project#reload_portfolio</tt>
         
     | 
| 
      
 353 
     | 
    
         
            +
                  # * <tt>Project#project_manager</tt>, <tt>Project#project_manager=(project_manager)</tt>, <tt>Project#reload_project_manager</tt>
         
     | 
| 
      
 354 
     | 
    
         
            +
                  # * <tt>Project#milestones.empty?</tt>, <tt>Project#milestones.size</tt>, <tt>Project#milestones</tt>, <tt>Project#milestones<<(milestone)</tt>,
         
     | 
| 
      
 355 
     | 
    
         
            +
                  #   <tt>Project#milestones.delete(milestone)</tt>, <tt>Project#milestones.destroy(milestone)</tt>, <tt>Project#milestones.find(milestone_id)</tt>,
         
     | 
| 
      
 356 
     | 
    
         
            +
                  #   <tt>Project#milestones.build</tt>, <tt>Project#milestones.create</tt>
         
     | 
| 
      
 357 
     | 
    
         
            +
                  # * <tt>Project#categories.empty?</tt>, <tt>Project#categories.size</tt>, <tt>Project#categories</tt>, <tt>Project#categories<<(category1)</tt>,
         
     | 
| 
      
 358 
     | 
    
         
            +
                  #   <tt>Project#categories.delete(category1)</tt>, <tt>Project#categories.destroy(category1)</tt>
         
     | 
| 
       302 
359 
     | 
    
         
             
                  #
         
     | 
| 
       303 
360 
     | 
    
         
             
                  # === A word of warning
         
     | 
| 
       304 
361 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -320,6 +377,8 @@ module ActiveRecord 
     | 
|
| 
       320 
377 
     | 
    
         
             
                  #   create_other(attributes={})       |     X      |              |    X
         
     | 
| 
       321 
378 
     | 
    
         
             
                  #   create_other!(attributes={})      |     X      |              |    X
         
     | 
| 
       322 
379 
     | 
    
         
             
                  #   reload_other                      |     X      |      X       |    X
         
     | 
| 
      
 380 
     | 
    
         
            +
                  #   other_changed?                    |     X      |      X       |
         
     | 
| 
      
 381 
     | 
    
         
            +
                  #   other_previously_changed?         |     X      |      X       |
         
     | 
| 
       323 
382 
     | 
    
         
             
                  #
         
     | 
| 
       324 
383 
     | 
    
         
             
                  # === Collection associations (one-to-many / many-to-many)
         
     | 
| 
       325 
384 
     | 
    
         
             
                  #                                     |       |          | has_many
         
     | 
| 
         @@ -536,19 +595,27 @@ module ActiveRecord 
     | 
|
| 
       536 
595 
     | 
    
         
             
                  # you can also define callbacks that get triggered when you add an object to or remove an
         
     | 
| 
       537 
596 
     | 
    
         
             
                  # object from an association collection.
         
     | 
| 
       538 
597 
     | 
    
         
             
                  #
         
     | 
| 
       539 
     | 
    
         
            -
                  #   class  
     | 
| 
       540 
     | 
    
         
            -
                  #      
     | 
| 
      
 598 
     | 
    
         
            +
                  #   class Firm < ActiveRecord::Base
         
     | 
| 
      
 599 
     | 
    
         
            +
                  #     has_many :clients,
         
     | 
| 
      
 600 
     | 
    
         
            +
                  #              dependent: :destroy,
         
     | 
| 
      
 601 
     | 
    
         
            +
                  #              after_add: :congratulate_client,
         
     | 
| 
      
 602 
     | 
    
         
            +
                  #              after_remove: :log_after_remove
         
     | 
| 
       541 
603 
     | 
    
         
             
                  #
         
     | 
| 
       542 
     | 
    
         
            -
                  #     def  
     | 
| 
       543 
     | 
    
         
            -
                  #       ...
         
     | 
| 
      
 604 
     | 
    
         
            +
                  #     def congratulate_client(record)
         
     | 
| 
      
 605 
     | 
    
         
            +
                  #       # ...
         
     | 
| 
      
 606 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 607 
     | 
    
         
            +
                  #
         
     | 
| 
      
 608 
     | 
    
         
            +
                  #     def log_after_remove(record)
         
     | 
| 
      
 609 
     | 
    
         
            +
                  #       # ...
         
     | 
| 
       544 
610 
     | 
    
         
             
                  #     end
         
     | 
| 
       545 
     | 
    
         
            -
                  #   end
         
     | 
| 
       546 
611 
     | 
    
         
             
                  #
         
     | 
| 
       547 
612 
     | 
    
         
             
                  # It's possible to stack callbacks by passing them as an array. Example:
         
     | 
| 
       548 
613 
     | 
    
         
             
                  #
         
     | 
| 
       549 
     | 
    
         
            -
                  #   class  
     | 
| 
       550 
     | 
    
         
            -
                  #      
     | 
| 
       551 
     | 
    
         
            -
                  # 
     | 
| 
      
 614 
     | 
    
         
            +
                  #   class Firm < ActiveRecord::Base
         
     | 
| 
      
 615 
     | 
    
         
            +
                  #     has_many :clients,
         
     | 
| 
      
 616 
     | 
    
         
            +
                  #              dependent: :destroy,
         
     | 
| 
      
 617 
     | 
    
         
            +
                  #              after_add: [:congratulate_client, -> (firm, record) { firm.log << "after_adding#{record.id}" }],
         
     | 
| 
      
 618 
     | 
    
         
            +
                  #              after_remove: :log_after_remove
         
     | 
| 
       552 
619 
     | 
    
         
             
                  #   end
         
     | 
| 
       553 
620 
     | 
    
         
             
                  #
         
     | 
| 
       554 
621 
     | 
    
         
             
                  # Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
         
     | 
| 
         @@ -559,6 +626,18 @@ module ActiveRecord 
     | 
|
| 
       559 
626 
     | 
    
         
             
                  # Similarly, if any of the +before_remove+ callbacks throw an exception, the object
         
     | 
| 
       560 
627 
     | 
    
         
             
                  # will not be removed from the collection.
         
     | 
| 
       561 
628 
     | 
    
         
             
                  #
         
     | 
| 
      
 629 
     | 
    
         
            +
                  # Note: To trigger remove callbacks, you must use +destroy+ / +destroy_all+ methods. For example:
         
     | 
| 
      
 630 
     | 
    
         
            +
                  #
         
     | 
| 
      
 631 
     | 
    
         
            +
                  #   * <tt>firm.clients.destroy(client)</tt>
         
     | 
| 
      
 632 
     | 
    
         
            +
                  #   * <tt>firm.clients.destroy(*clients)</tt>
         
     | 
| 
      
 633 
     | 
    
         
            +
                  #   * <tt>firm.clients.destroy_all</tt>
         
     | 
| 
      
 634 
     | 
    
         
            +
                  #
         
     | 
| 
      
 635 
     | 
    
         
            +
                  # +delete+ / +delete_all+ methods like the following do *not* trigger remove callbacks:
         
     | 
| 
      
 636 
     | 
    
         
            +
                  #
         
     | 
| 
      
 637 
     | 
    
         
            +
                  #   * <tt>firm.clients.delete(client)</tt>
         
     | 
| 
      
 638 
     | 
    
         
            +
                  #   * <tt>firm.clients.delete(*clients)</tt>
         
     | 
| 
      
 639 
     | 
    
         
            +
                  #   * <tt>firm.clients.delete_all</tt>
         
     | 
| 
      
 640 
     | 
    
         
            +
                  #
         
     | 
| 
       562 
641 
     | 
    
         
             
                  # == Association extensions
         
     | 
| 
       563 
642 
     | 
    
         
             
                  #
         
     | 
| 
       564 
643 
     | 
    
         
             
                  # The proxy objects that control the access to associations can be extended through anonymous
         
     | 
| 
         @@ -702,9 +781,10 @@ module ActiveRecord 
     | 
|
| 
       702 
781 
     | 
    
         
             
                  # inverse detection only works on #has_many, #has_one, and
         
     | 
| 
       703 
782 
     | 
    
         
             
                  # #belongs_to associations.
         
     | 
| 
       704 
783 
     | 
    
         
             
                  #
         
     | 
| 
       705 
     | 
    
         
            -
                  #  
     | 
| 
       706 
     | 
    
         
            -
                  #  
     | 
| 
       707 
     | 
    
         
            -
                  #  
     | 
| 
      
 784 
     | 
    
         
            +
                  # <tt>:foreign_key</tt> and <tt>:through</tt> options on the associations
         
     | 
| 
      
 785 
     | 
    
         
            +
                  # will also prevent the association's inverse from being found automatically,
         
     | 
| 
      
 786 
     | 
    
         
            +
                  # as will a custom scopes in some cases. See further details in the
         
     | 
| 
      
 787 
     | 
    
         
            +
                  # {Active Record Associations guide}[https://guides.rubyonrails.org/association_basics.html#bi-directional-associations].
         
     | 
| 
       708 
788 
     | 
    
         
             
                  #
         
     | 
| 
       709 
789 
     | 
    
         
             
                  # The automatic guessing of the inverse association uses a heuristic based
         
     | 
| 
       710 
790 
     | 
    
         
             
                  # on the name of the class, so it may not work for all associations,
         
     | 
| 
         @@ -1291,10 +1371,15 @@ module ActiveRecord 
     | 
|
| 
       1291 
1371 
     | 
    
         
             
                    #   similar callbacks may affect the <tt>:dependent</tt> behavior, and the
         
     | 
| 
       1292 
1372 
     | 
    
         
             
                    #   <tt>:dependent</tt> behavior may affect other callbacks.
         
     | 
| 
       1293 
1373 
     | 
    
         
             
                    #
         
     | 
| 
      
 1374 
     | 
    
         
            +
                    #   * <tt>nil</tt> do nothing (default).
         
     | 
| 
       1294 
1375 
     | 
    
         
             
                    #   * <tt>:destroy</tt> causes all the associated objects to also be destroyed.
         
     | 
| 
      
 1376 
     | 
    
         
            +
                    #   * <tt>:destroy_async</tt> destroys all the associated objects in a background job. <b>WARNING:</b> Do not use
         
     | 
| 
      
 1377 
     | 
    
         
            +
                    #     this option if the association is backed by foreign key constraints in your database. The foreign key
         
     | 
| 
      
 1378 
     | 
    
         
            +
                    #     constraint actions will occur inside the same transaction that deletes its owner.
         
     | 
| 
       1295 
1379 
     | 
    
         
             
                    #   * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
         
     | 
| 
       1296 
     | 
    
         
            -
                    #   * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+.  
     | 
| 
       1297 
     | 
    
         
            -
                    # 
     | 
| 
      
 1380 
     | 
    
         
            +
                    #   * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
         
     | 
| 
      
 1381 
     | 
    
         
            +
                    #     on polymorphic associations. Callbacks are not executed.
         
     | 
| 
      
 1382 
     | 
    
         
            +
                    #   * <tt>:restrict_with_exception</tt> causes an <tt>ActiveRecord::DeleteRestrictionError</tt> exception to be raised if there are any associated records.
         
     | 
| 
       1298 
1383 
     | 
    
         
             
                    #   * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
         
     | 
| 
       1299 
1384 
     | 
    
         
             
                    #
         
     | 
| 
       1300 
1385 
     | 
    
         
             
                    #   If using with the <tt>:through</tt> option, the association on the join model must be
         
     | 
| 
         @@ -1327,6 +1412,11 @@ module ActiveRecord 
     | 
|
| 
       1327 
1412 
     | 
    
         
             
                    #   join model. This allows associated records to be built which will automatically create
         
     | 
| 
       1328 
1413 
     | 
    
         
             
                    #   the appropriate join model records when they are saved. (See the 'Association Join Models'
         
     | 
| 
       1329 
1414 
     | 
    
         
             
                    #   section above.)
         
     | 
| 
      
 1415 
     | 
    
         
            +
                    # [:disable_joins]
         
     | 
| 
      
 1416 
     | 
    
         
            +
                    #   Specifies whether joins should be skipped for an association. If set to true, two or more queries
         
     | 
| 
      
 1417 
     | 
    
         
            +
                    #   will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
         
     | 
| 
      
 1418 
     | 
    
         
            +
                    #   due to database limitations. This option is only applicable on `has_many :through` associations as
         
     | 
| 
      
 1419 
     | 
    
         
            +
                    #   `has_many` alone do not perform a join.
         
     | 
| 
       1330 
1420 
     | 
    
         
             
                    # [:source]
         
     | 
| 
       1331 
1421 
     | 
    
         
             
                    #   Specifies the source association name used by #has_many <tt>:through</tt> queries.
         
     | 
| 
       1332 
1422 
     | 
    
         
             
                    #   Only use it if the name cannot be inferred from the association.
         
     | 
| 
         @@ -1355,6 +1445,12 @@ module ActiveRecord 
     | 
|
| 
       1355 
1445 
     | 
    
         
             
                    #   Specifies a module or array of modules that will be extended into the association object returned.
         
     | 
| 
       1356 
1446 
     | 
    
         
             
                    #   Useful for defining methods on associations, especially when they should be shared between multiple
         
     | 
| 
       1357 
1447 
     | 
    
         
             
                    #   association objects.
         
     | 
| 
      
 1448 
     | 
    
         
            +
                    # [:strict_loading]
         
     | 
| 
      
 1449 
     | 
    
         
            +
                    #   When set to +true+, enforces strict loading every time the associated record is loaded through this
         
     | 
| 
      
 1450 
     | 
    
         
            +
                    #   association.
         
     | 
| 
      
 1451 
     | 
    
         
            +
                    # [:ensuring_owner_was]
         
     | 
| 
      
 1452 
     | 
    
         
            +
                    #   Specifies an instance method to be called on the owner. The method must return true in order for the
         
     | 
| 
      
 1453 
     | 
    
         
            +
                    #   associated records to be deleted in a background job.
         
     | 
| 
       1358 
1454 
     | 
    
         
             
                    #
         
     | 
| 
       1359 
1455 
     | 
    
         
             
                    # Option examples:
         
     | 
| 
       1360 
1456 
     | 
    
         
             
                    #   has_many :comments, -> { order("posted_on") }
         
     | 
| 
         @@ -1365,6 +1461,8 @@ module ActiveRecord 
     | 
|
| 
       1365 
1461 
     | 
    
         
             
                    #   has_many :tags, as: :taggable
         
     | 
| 
       1366 
1462 
     | 
    
         
             
                    #   has_many :reports, -> { readonly }
         
     | 
| 
       1367 
1463 
     | 
    
         
             
                    #   has_many :subscribers, through: :subscriptions, source: :user
         
     | 
| 
      
 1464 
     | 
    
         
            +
                    #   has_many :subscribers, through: :subscriptions, disable_joins: true
         
     | 
| 
      
 1465 
     | 
    
         
            +
                    #   has_many :comments, strict_loading: true
         
     | 
| 
       1368 
1466 
     | 
    
         
             
                    def has_many(name, scope = nil, **options, &extension)
         
     | 
| 
       1369 
1467 
     | 
    
         
             
                      reflection = Builder::HasMany.build(self, name, scope, options, &extension)
         
     | 
| 
       1370 
1468 
     | 
    
         
             
                      Reflection.add_reflection self, name, reflection
         
     | 
| 
         @@ -1434,10 +1532,15 @@ module ActiveRecord 
     | 
|
| 
       1434 
1532 
     | 
    
         
             
                    #   Controls what happens to the associated object when
         
     | 
| 
       1435 
1533 
     | 
    
         
             
                    #   its owner is destroyed:
         
     | 
| 
       1436 
1534 
     | 
    
         
             
                    #
         
     | 
| 
      
 1535 
     | 
    
         
            +
                    #   * <tt>nil</tt> do nothing (default).
         
     | 
| 
       1437 
1536 
     | 
    
         
             
                    #   * <tt>:destroy</tt> causes the associated object to also be destroyed
         
     | 
| 
      
 1537 
     | 
    
         
            +
                    #   * <tt>:destroy_async</tt> causes the associated object to be destroyed in a background job. <b>WARNING:</b> Do not use
         
     | 
| 
      
 1538 
     | 
    
         
            +
                    #     this option if the association is backed by foreign key constraints in your database. The foreign key
         
     | 
| 
      
 1539 
     | 
    
         
            +
                    #     constraint actions will occur inside the same transaction that deletes its owner.
         
     | 
| 
       1438 
1540 
     | 
    
         
             
                    #   * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
         
     | 
| 
       1439 
     | 
    
         
            -
                    #   * <tt>:nullify</tt> causes the foreign key to be set to +NULL+.  
     | 
| 
       1440 
     | 
    
         
            -
                    # 
     | 
| 
      
 1541 
     | 
    
         
            +
                    #   * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
         
     | 
| 
      
 1542 
     | 
    
         
            +
                    #     on polymorphic associations. Callbacks are not executed.
         
     | 
| 
      
 1543 
     | 
    
         
            +
                    #   * <tt>:restrict_with_exception</tt> causes an <tt>ActiveRecord::DeleteRestrictionError</tt> exception to be raised if there is an associated record
         
     | 
| 
       1441 
1544 
     | 
    
         
             
                    #   * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
         
     | 
| 
       1442 
1545 
     | 
    
         
             
                    #
         
     | 
| 
       1443 
1546 
     | 
    
         
             
                    #   Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
         
     | 
| 
         @@ -1464,8 +1567,21 @@ module ActiveRecord 
     | 
|
| 
       1464 
1567 
     | 
    
         
             
                    #   source reflection. You can only use a <tt>:through</tt> query through a #has_one
         
     | 
| 
       1465 
1568 
     | 
    
         
             
                    #   or #belongs_to association on the join model.
         
     | 
| 
       1466 
1569 
     | 
    
         
             
                    #
         
     | 
| 
      
 1570 
     | 
    
         
            +
                    #   If the association on the join model is a #belongs_to, the collection can be modified
         
     | 
| 
      
 1571 
     | 
    
         
            +
                    #   and the records on the <tt>:through</tt> model will be automatically created and removed
         
     | 
| 
      
 1572 
     | 
    
         
            +
                    #   as appropriate. Otherwise, the collection is read-only, so you should manipulate the
         
     | 
| 
      
 1573 
     | 
    
         
            +
                    #   <tt>:through</tt> association directly.
         
     | 
| 
      
 1574 
     | 
    
         
            +
                    #
         
     | 
| 
       1467 
1575 
     | 
    
         
             
                    #   If you are going to modify the association (rather than just read from it), then it is
         
     | 
| 
       1468 
     | 
    
         
            -
                    #   a good idea to set the <tt>:inverse_of</tt> option 
     | 
| 
      
 1576 
     | 
    
         
            +
                    #   a good idea to set the <tt>:inverse_of</tt> option on the source association on the
         
     | 
| 
      
 1577 
     | 
    
         
            +
                    #   join model. This allows associated records to be built which will automatically create
         
     | 
| 
      
 1578 
     | 
    
         
            +
                    #   the appropriate join model records when they are saved. (See the 'Association Join Models'
         
     | 
| 
      
 1579 
     | 
    
         
            +
                    #   section above.)
         
     | 
| 
      
 1580 
     | 
    
         
            +
                    # [:disable_joins]
         
     | 
| 
      
 1581 
     | 
    
         
            +
                    #   Specifies whether joins should be skipped for an association. If set to true, two or more queries
         
     | 
| 
      
 1582 
     | 
    
         
            +
                    #   will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
         
     | 
| 
      
 1583 
     | 
    
         
            +
                    #   due to database limitations. This option is only applicable on `has_one :through` associations as
         
     | 
| 
      
 1584 
     | 
    
         
            +
                    #   `has_one` alone does not perform a join.
         
     | 
| 
       1469 
1585 
     | 
    
         
             
                    # [:source]
         
     | 
| 
       1470 
1586 
     | 
    
         
             
                    #   Specifies the source association name used by #has_one <tt>:through</tt> queries.
         
     | 
| 
       1471 
1587 
     | 
    
         
             
                    #   Only use it if the name cannot be inferred from the association.
         
     | 
| 
         @@ -1492,6 +1608,11 @@ module ActiveRecord 
     | 
|
| 
       1492 
1608 
     | 
    
         
             
                    #   When set to +true+, the association will also have its presence validated.
         
     | 
| 
       1493 
1609 
     | 
    
         
             
                    #   This will validate the association itself, not the id. You can use
         
     | 
| 
       1494 
1610 
     | 
    
         
             
                    #   +:inverse_of+ to avoid an extra query during validation.
         
     | 
| 
      
 1611 
     | 
    
         
            +
                    # [:strict_loading]
         
     | 
| 
      
 1612 
     | 
    
         
            +
                    #   Enforces strict loading every time the associated record is loaded through this association.
         
     | 
| 
      
 1613 
     | 
    
         
            +
                    # [:ensuring_owner_was]
         
     | 
| 
      
 1614 
     | 
    
         
            +
                    #   Specifies an instance method to be called on the owner. The method must return true in order for the
         
     | 
| 
      
 1615 
     | 
    
         
            +
                    #   associated records to be deleted in a background job.
         
     | 
| 
       1495 
1616 
     | 
    
         
             
                    #
         
     | 
| 
       1496 
1617 
     | 
    
         
             
                    # Option examples:
         
     | 
| 
       1497 
1618 
     | 
    
         
             
                    #   has_one :credit_card, dependent: :destroy  # destroys the associated credit card
         
     | 
| 
         @@ -1502,8 +1623,10 @@ module ActiveRecord 
     | 
|
| 
       1502 
1623 
     | 
    
         
             
                    #   has_one :attachment, as: :attachable
         
     | 
| 
       1503 
1624 
     | 
    
         
             
                    #   has_one :boss, -> { readonly }
         
     | 
| 
       1504 
1625 
     | 
    
         
             
                    #   has_one :club, through: :membership
         
     | 
| 
      
 1626 
     | 
    
         
            +
                    #   has_one :club, through: :membership, disable_joins: true
         
     | 
| 
       1505 
1627 
     | 
    
         
             
                    #   has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
         
     | 
| 
       1506 
1628 
     | 
    
         
             
                    #   has_one :credit_card, required: true
         
     | 
| 
      
 1629 
     | 
    
         
            +
                    #   has_one :credit_card, strict_loading: true
         
     | 
| 
       1507 
1630 
     | 
    
         
             
                    def has_one(name, scope = nil, **options)
         
     | 
| 
       1508 
1631 
     | 
    
         
             
                      reflection = Builder::HasOne.build(self, name, scope, options)
         
     | 
| 
       1509 
1632 
     | 
    
         
             
                      Reflection.add_reflection self, name, reflection
         
     | 
| 
         @@ -1524,6 +1647,7 @@ module ActiveRecord 
     | 
|
| 
       1524 
1647 
     | 
    
         
             
                    #   Returns the associated object. +nil+ is returned if none is found.
         
     | 
| 
       1525 
1648 
     | 
    
         
             
                    # [association=(associate)]
         
     | 
| 
       1526 
1649 
     | 
    
         
             
                    #   Assigns the associate object, extracts the primary key, and sets it as the foreign key.
         
     | 
| 
      
 1650 
     | 
    
         
            +
                    #   No modification or deletion of existing records takes place.
         
     | 
| 
       1527 
1651 
     | 
    
         
             
                    # [build_association(attributes = {})]
         
     | 
| 
       1528 
1652 
     | 
    
         
             
                    #   Returns a new object of the associated type that has been instantiated
         
     | 
| 
       1529 
1653 
     | 
    
         
             
                    #   with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
         
     | 
| 
         @@ -1536,6 +1660,10 @@ module ActiveRecord 
     | 
|
| 
       1536 
1660 
     | 
    
         
             
                    #   if the record is invalid.
         
     | 
| 
       1537 
1661 
     | 
    
         
             
                    # [reload_association]
         
     | 
| 
       1538 
1662 
     | 
    
         
             
                    #   Returns the associated object, forcing a database read.
         
     | 
| 
      
 1663 
     | 
    
         
            +
                    # [association_changed?]
         
     | 
| 
      
 1664 
     | 
    
         
            +
                    #   Returns true if a new associate object has been assigned and the next save will update the foreign key.
         
     | 
| 
      
 1665 
     | 
    
         
            +
                    # [association_previously_changed?]
         
     | 
| 
      
 1666 
     | 
    
         
            +
                    #   Returns true if the previous save updated the association to reference a new associate object.
         
     | 
| 
       1539 
1667 
     | 
    
         
             
                    #
         
     | 
| 
       1540 
1668 
     | 
    
         
             
                    # === Example
         
     | 
| 
       1541 
1669 
     | 
    
         
             
                    #
         
     | 
| 
         @@ -1546,6 +1674,8 @@ module ActiveRecord 
     | 
|
| 
       1546 
1674 
     | 
    
         
             
                    # * <tt>Post#create_author</tt> (similar to <tt>post.author = Author.new; post.author.save; post.author</tt>)
         
     | 
| 
       1547 
1675 
     | 
    
         
             
                    # * <tt>Post#create_author!</tt> (similar to <tt>post.author = Author.new; post.author.save!; post.author</tt>)
         
     | 
| 
       1548 
1676 
     | 
    
         
             
                    # * <tt>Post#reload_author</tt>
         
     | 
| 
      
 1677 
     | 
    
         
            +
                    # * <tt>Post#author_changed?</tt>
         
     | 
| 
      
 1678 
     | 
    
         
            +
                    # * <tt>Post#author_previously_changed?</tt>
         
     | 
| 
       1549 
1679 
     | 
    
         
             
                    # The declaration can also include an +options+ hash to specialize the behavior of the association.
         
     | 
| 
       1550 
1680 
     | 
    
         
             
                    #
         
     | 
| 
       1551 
1681 
     | 
    
         
             
                    # === Scopes
         
     | 
| 
         @@ -1581,10 +1711,11 @@ module ActiveRecord 
     | 
|
| 
       1581 
1711 
     | 
    
         
             
                    #   association will use "taggable_type" as the default <tt>:foreign_type</tt>.
         
     | 
| 
       1582 
1712 
     | 
    
         
             
                    # [:primary_key]
         
     | 
| 
       1583 
1713 
     | 
    
         
             
                    #   Specify the method that returns the primary key of associated object used for the association.
         
     | 
| 
       1584 
     | 
    
         
            -
                    #   By default this is id 
     | 
| 
      
 1714 
     | 
    
         
            +
                    #   By default this is +id+.
         
     | 
| 
       1585 
1715 
     | 
    
         
             
                    # [:dependent]
         
     | 
| 
       1586 
1716 
     | 
    
         
             
                    #   If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
         
     | 
| 
       1587 
     | 
    
         
            -
                    #   <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
         
     | 
| 
      
 1717 
     | 
    
         
            +
                    #   <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to
         
     | 
| 
      
 1718 
     | 
    
         
            +
                    #   <tt>:destroy_async</tt>, the associated object is scheduled to be destroyed in a background job.
         
     | 
| 
       1588 
1719 
     | 
    
         
             
                    #   This option should not be specified when #belongs_to is used in conjunction with
         
     | 
| 
       1589 
1720 
     | 
    
         
             
                    #   a #has_many relationship on another class because of the potential to leave
         
     | 
| 
       1590 
1721 
     | 
    
         
             
                    #   orphaned records behind.
         
     | 
| 
         @@ -1636,6 +1767,11 @@ module ActiveRecord 
     | 
|
| 
       1636 
1767 
     | 
    
         
             
                    # [:default]
         
     | 
| 
       1637 
1768 
     | 
    
         
             
                    #   Provide a callable (i.e. proc or lambda) to specify that the association should
         
     | 
| 
       1638 
1769 
     | 
    
         
             
                    #   be initialized with a particular record before validation.
         
     | 
| 
      
 1770 
     | 
    
         
            +
                    # [:strict_loading]
         
     | 
| 
      
 1771 
     | 
    
         
            +
                    #   Enforces strict loading every time the associated record is loaded through this association.
         
     | 
| 
      
 1772 
     | 
    
         
            +
                    # [:ensuring_owner_was]
         
     | 
| 
      
 1773 
     | 
    
         
            +
                    #   Specifies an instance method to be called on the owner. The method must return true in order for the
         
     | 
| 
      
 1774 
     | 
    
         
            +
                    #   associated records to be deleted in a background job.
         
     | 
| 
       1639 
1775 
     | 
    
         
             
                    #
         
     | 
| 
       1640 
1776 
     | 
    
         
             
                    # Option examples:
         
     | 
| 
       1641 
1777 
     | 
    
         
             
                    #   belongs_to :firm, foreign_key: "client_of"
         
     | 
| 
         @@ -1650,6 +1786,7 @@ module ActiveRecord 
     | 
|
| 
       1650 
1786 
     | 
    
         
             
                    #   belongs_to :company, touch: :employees_last_updated_at
         
     | 
| 
       1651 
1787 
     | 
    
         
             
                    #   belongs_to :user, optional: true
         
     | 
| 
       1652 
1788 
     | 
    
         
             
                    #   belongs_to :account, default: -> { company.account }
         
     | 
| 
      
 1789 
     | 
    
         
            +
                    #   belongs_to :account, strict_loading: true
         
     | 
| 
       1653 
1790 
     | 
    
         
             
                    def belongs_to(name, scope = nil, **options)
         
     | 
| 
       1654 
1791 
     | 
    
         
             
                      reflection = Builder::BelongsTo.build(self, name, scope, options)
         
     | 
| 
       1655 
1792 
     | 
    
         
             
                      Reflection.add_reflection self, name, reflection
         
     | 
| 
         @@ -1672,7 +1809,7 @@ module ActiveRecord 
     | 
|
| 
       1672 
1809 
     | 
    
         
             
                    # The join table should not have a primary key or a model associated with it. You must manually generate the
         
     | 
| 
       1673 
1810 
     | 
    
         
             
                    # join table with a migration such as this:
         
     | 
| 
       1674 
1811 
     | 
    
         
             
                    #
         
     | 
| 
       1675 
     | 
    
         
            -
                    #   class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[ 
     | 
| 
      
 1812 
     | 
    
         
            +
                    #   class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.0]
         
     | 
| 
       1676 
1813 
     | 
    
         
             
                    #     def change
         
     | 
| 
       1677 
1814 
     | 
    
         
             
                    #       create_join_table :developers, :projects
         
     | 
| 
       1678 
1815 
     | 
    
         
             
                    #     end
         
     | 
| 
         @@ -1761,6 +1898,7 @@ module ActiveRecord 
     | 
|
| 
       1761 
1898 
     | 
    
         
             
                    #   has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
         
     | 
| 
       1762 
1899 
     | 
    
         
             
                    #   has_and_belongs_to_many :categories, ->(post) {
         
     | 
| 
       1763 
1900 
     | 
    
         
             
                    #     where("default_category = ?", post.default_category)
         
     | 
| 
      
 1901 
     | 
    
         
            +
                    #   }
         
     | 
| 
       1764 
1902 
     | 
    
         
             
                    #
         
     | 
| 
       1765 
1903 
     | 
    
         
             
                    # === Extensions
         
     | 
| 
       1766 
1904 
     | 
    
         
             
                    #
         
     | 
| 
         @@ -1811,6 +1949,8 @@ module ActiveRecord 
     | 
|
| 
       1811 
1949 
     | 
    
         
             
                    #
         
     | 
| 
       1812 
1950 
     | 
    
         
             
                    #   Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
         
     | 
| 
       1813 
1951 
     | 
    
         
             
                    #   <tt>:autosave</tt> to <tt>true</tt>.
         
     | 
| 
      
 1952 
     | 
    
         
            +
                    # [:strict_loading]
         
     | 
| 
      
 1953 
     | 
    
         
            +
                    #   Enforces strict loading every time an associated record is loaded through this association.
         
     | 
| 
       1814 
1954 
     | 
    
         
             
                    #
         
     | 
| 
       1815 
1955 
     | 
    
         
             
                    # Option examples:
         
     | 
| 
       1816 
1956 
     | 
    
         
             
                    #   has_and_belongs_to_many :projects
         
     | 
| 
         @@ -1818,6 +1958,7 @@ module ActiveRecord 
     | 
|
| 
       1818 
1958 
     | 
    
         
             
                    #   has_and_belongs_to_many :nations, class_name: "Country"
         
     | 
| 
       1819 
1959 
     | 
    
         
             
                    #   has_and_belongs_to_many :categories, join_table: "prods_cats"
         
     | 
| 
       1820 
1960 
     | 
    
         
             
                    #   has_and_belongs_to_many :categories, -> { readonly }
         
     | 
| 
      
 1961 
     | 
    
         
            +
                    #   has_and_belongs_to_many :categories, strict_loading: true
         
     | 
| 
       1821 
1962 
     | 
    
         
             
                    def has_and_belongs_to_many(name, scope = nil, **options, &extension)
         
     | 
| 
       1822 
1963 
     | 
    
         
             
                      habtm_reflection = ActiveRecord::Reflection::HasAndBelongsToManyReflection.new(name, scope, options, self)
         
     | 
| 
       1823 
1964 
     | 
    
         | 
| 
         @@ -1848,11 +1989,11 @@ module ActiveRecord 
     | 
|
| 
       1848 
1989 
     | 
    
         
             
                      hm_options[:through] = middle_reflection.name
         
     | 
| 
       1849 
1990 
     | 
    
         
             
                      hm_options[:source] = join_model.right_reflection.name
         
     | 
| 
       1850 
1991 
     | 
    
         | 
| 
       1851 
     | 
    
         
            -
                      [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k|
         
     | 
| 
      
 1992 
     | 
    
         
            +
                      [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend, :strict_loading].each do |k|
         
     | 
| 
       1852 
1993 
     | 
    
         
             
                        hm_options[k] = options[k] if options.key? k
         
     | 
| 
       1853 
1994 
     | 
    
         
             
                      end
         
     | 
| 
       1854 
1995 
     | 
    
         | 
| 
       1855 
     | 
    
         
            -
                      has_many name, scope, hm_options, &extension
         
     | 
| 
      
 1996 
     | 
    
         
            +
                      has_many name, scope, **hm_options, &extension
         
     | 
| 
       1856 
1997 
     | 
    
         
             
                      _reflections[name.to_s].parent_reflection = habtm_reflection
         
     | 
| 
       1857 
1998 
     | 
    
         
             
                    end
         
     | 
| 
       1858 
1999 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -0,0 +1,60 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ActiveRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
              class AsynchronousQueriesTracker # :nodoc:
         
     | 
| 
      
 5 
     | 
    
         
            +
                module NullSession # :nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def active?
         
     | 
| 
      
 8 
     | 
    
         
            +
                      true
         
     | 
| 
      
 9 
     | 
    
         
            +
                    end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    def finalize
         
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                class Session # :nodoc:
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @active = true
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def active?
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @active
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def finalize
         
     | 
| 
      
 26 
     | 
    
         
            +
                    @active = false
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def install_executor_hooks(executor = ActiveSupport::Executor)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    executor.register_hook(self)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 36 
     | 
    
         
            +
                    ActiveRecord::Base.asynchronous_queries_tracker.start_session
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def complete(asynchronous_queries_tracker)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    asynchronous_queries_tracker.finalize_session
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                attr_reader :current_session
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 47 
     | 
    
         
            +
                  @current_session = NullSession
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                def start_session
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @current_session = Session.new
         
     | 
| 
      
 52 
     | 
    
         
            +
                  self
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def finalize_session
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @current_session.finalize
         
     | 
| 
      
 57 
     | 
    
         
            +
                  @current_session = NullSession
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     |