activerecord 6.0.0 → 7.2.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +996 -594
- data/MIT-LICENSE +1 -1
- data/README.rdoc +34 -34
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +22 -20
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations/alias_tracker.rb +41 -30
- data/lib/active_record/associations/association.rb +106 -41
- data/lib/active_record/associations/association_scope.rb +30 -21
- data/lib/active_record/associations/belongs_to_association.rb +69 -14
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +20 -6
- data/lib/active_record/associations/builder/association.rb +39 -6
- data/lib/active_record/associations/builder/belongs_to.rb +47 -17
- data/lib/active_record/associations/builder/collection_association.rb +14 -6
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -10
- data/lib/active_record/associations/builder/has_many.rb +7 -3
- data/lib/active_record/associations/builder/has_one.rb +13 -16
- data/lib/active_record/associations/builder/singular_association.rb +7 -3
- data/lib/active_record/associations/collection_association.rb +90 -53
- data/lib/active_record/associations/collection_proxy.rb +54 -19
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +21 -1
- data/lib/active_record/associations/has_many_association.rb +41 -10
- data/lib/active_record/associations/has_many_through_association.rb +29 -12
- data/lib/active_record/associations/has_one_association.rb +33 -9
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +41 -17
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/join_dependency.rb +97 -54
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +237 -54
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +153 -0
- data/lib/active_record/associations/preloader/through_association.rb +51 -17
- data/lib/active_record/associations/preloader.rb +55 -121
- data/lib/active_record/associations/singular_association.rb +16 -4
- data/lib/active_record/associations/through_association.rb +26 -15
- data/lib/active_record/associations.rb +454 -440
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +11 -14
- data/lib/active_record/attribute_methods/before_type_cast.rb +36 -11
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +75 -34
- data/lib/active_record/attribute_methods/primary_key.rb +53 -31
- data/lib/active_record/attribute_methods/query.rb +31 -22
- data/lib/active_record/attribute_methods/read.rb +16 -17
- data/lib/active_record/attribute_methods/serialization.rb +177 -35
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +18 -15
- data/lib/active_record/attribute_methods/write.rb +16 -28
- data/lib/active_record/attribute_methods.rb +227 -100
- data/lib/active_record/attributes.rb +94 -56
- data/lib/active_record/autosave_association.rb +119 -73
- data/lib/active_record/base.rb +31 -21
- data/lib/active_record/callbacks.rb +168 -55
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -25
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +367 -565
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -57
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +277 -89
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +241 -69
- data/lib/active_record/connection_adapters/abstract/quoting.rb +122 -134
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +324 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +611 -211
- data/lib/active_record/connection_adapters/abstract/transaction.rb +425 -82
- data/lib/active_record/connection_adapters/abstract_adapter.rb +698 -211
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +464 -239
- data/lib/active_record/connection_adapters/column.rb +28 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +32 -137
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +90 -43
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +41 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +18 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +13 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +53 -15
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +127 -63
- data/lib/active_record/connection_adapters/pool_config.rb +83 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +54 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +127 -100
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +9 -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 +53 -15
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +35 -8
- 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 +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -4
- data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +139 -106
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +98 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +176 -4
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -118
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +585 -295
- data/lib/active_record/connection_adapters/schema_cache.rb +399 -60
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +99 -48
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +80 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +27 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +102 -24
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +425 -174
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -1
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
- data/lib/active_record/connection_adapters.rb +176 -0
- data/lib/active_record/connection_handling.rb +243 -115
- data/lib/active_record/core.rb +481 -199
- data/lib/active_record/counter_cache.rb +69 -32
- data/lib/active_record/database_configurations/connection_url_resolver.rb +107 -0
- data/lib/active_record/database_configurations/database_config.rb +77 -10
- data/lib/active_record/database_configurations/hash_config.rb +148 -26
- data/lib/active_record/database_configurations/url_config.rb +44 -45
- data/lib/active_record/database_configurations.rb +190 -114
- data/lib/active_record/delegated_type.rb +279 -0
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +38 -0
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +5 -6
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +230 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -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 +171 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +96 -0
- data/lib/active_record/encryption/null_encryptor.rb +25 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
- data/lib/active_record/encryption/scheme.rb +100 -0
- data/lib/active_record/encryption.rb +58 -0
- data/lib/active_record/enum.rb +224 -73
- data/lib/active_record/errors.rb +254 -36
- data/lib/active_record/explain.rb +30 -17
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +2 -2
- data/lib/active_record/fixture_set/file.rb +22 -15
- data/lib/active_record/fixture_set/model_metadata.rb +15 -6
- data/lib/active_record/fixture_set/render_context.rb +3 -1
- data/lib/active_record/fixture_set/table_row.rb +88 -16
- data/lib/active_record/fixture_set/table_rows.rb +4 -5
- data/lib/active_record/fixtures.rb +229 -116
- data/lib/active_record/future_result.rb +178 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +121 -48
- data/lib/active_record/insert_all.rb +178 -29
- data/lib/active_record/integration.rb +16 -14
- data/lib/active_record/internal_metadata.rb +132 -21
- data/lib/active_record/legacy_yaml_adapter.rb +3 -36
- data/lib/active_record/locking/optimistic.rb +64 -33
- data/lib/active_record/locking/pessimistic.rb +21 -8
- data/lib/active_record/log_subscriber.rb +61 -30
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +19 -19
- data/lib/active_record/middleware/database_selector.rb +25 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +160 -55
- data/lib/active_record/migration/compatibility.rb +286 -43
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +1 -2
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +421 -193
- data/lib/active_record/model_schema.rb +217 -125
- data/lib/active_record/nested_attributes.rb +62 -27
- data/lib/active_record/no_touching.rb +4 -4
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +322 -319
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -15
- data/lib/active_record/query_logs.rb +193 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +54 -14
- data/lib/active_record/railtie.rb +250 -72
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +25 -11
- data/lib/active_record/railties/databases.rake +312 -197
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +45 -3
- data/lib/active_record/reflection.rb +389 -146
- data/lib/active_record/relation/batches/batch_enumerator.rb +61 -16
- data/lib/active_record/relation/batches.rb +214 -73
- data/lib/active_record/relation/calculations.rb +379 -124
- data/lib/active_record/relation/delegation.rb +36 -23
- data/lib/active_record/relation/finder_methods.rb +159 -49
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +41 -33
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -11
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -7
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +20 -13
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +79 -53
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +1156 -279
- data/lib/active_record/relation/record_fetch_warning.rb +12 -11
- data/lib/active_record/relation/spawn_methods.rb +10 -9
- data/lib/active_record/relation/where_clause.rb +100 -66
- data/lib/active_record/relation.rb +829 -194
- data/lib/active_record/result.rb +76 -56
- data/lib/active_record/runtime_registry.rb +71 -13
- data/lib/active_record/sanitization.rb +86 -47
- data/lib/active_record/schema.rb +39 -23
- data/lib/active_record/schema_dumper.rb +140 -33
- data/lib/active_record/schema_migration.rb +74 -29
- data/lib/active_record/scoping/default.rb +73 -19
- data/lib/active_record/scoping/named.rb +10 -28
- data/lib/active_record/scoping.rb +65 -35
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +34 -8
- data/lib/active_record/serialization.rb +11 -4
- data/lib/active_record/signed_id.rb +138 -0
- data/lib/active_record/statement_cache.rb +26 -10
- data/lib/active_record/store.rb +19 -14
- data/lib/active_record/suppressor.rb +15 -17
- data/lib/active_record/table_metadata.rb +46 -36
- data/lib/active_record/tasks/database_tasks.rb +371 -205
- data/lib/active_record/tasks/mysql_database_tasks.rb +43 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +54 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -13
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +189 -104
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +35 -25
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +31 -27
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +131 -99
- data/lib/active_record/translation.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +33 -18
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +11 -6
- data/lib/active_record/type/time.rb +14 -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 +7 -2
- data/lib/active_record/type_caster/connection.rb +4 -5
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +13 -8
- data/lib/active_record/validations/numericality.rb +36 -0
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +88 -18
- data/lib/active_record/validations.rb +15 -8
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +446 -40
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/attributes/attribute.rb +4 -8
- data/lib/arel/collectors/bind.rb +8 -1
- data/lib/arel/collectors/composite.rb +15 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/crud.rb +30 -22
- data/lib/arel/delete_manager.rb +23 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/binary.rb +82 -9
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/casted.rb +22 -10
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +14 -13
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +68 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
- data/lib/arel/nodes/node.rb +122 -11
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/table_alias.rb +11 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/nodes/update_statement.rb +11 -4
- data/lib/arel/nodes.rb +10 -3
- data/lib/arel/predications.rb +31 -28
- data/lib/arel/select_manager.rb +18 -9
- data/lib/arel/table.rb +21 -10
- data/lib/arel/tree_manager.rb +8 -15
- data/lib/arel/update_manager.rb +25 -5
- data/lib/arel/visitors/dot.rb +94 -90
- data/lib/arel/visitors/mysql.rb +34 -6
- data/lib/arel/visitors/postgresql.rb +5 -16
- data/lib/arel/visitors/sqlite.rb +25 -1
- data/lib/arel/visitors/to_sql.rb +227 -81
- data/lib/arel/visitors/visitor.rb +2 -3
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel.rb +37 -15
- data/lib/rails/generators/active_record/application_record/USAGE +8 -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 +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +6 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/migration.rb +9 -3
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +49 -4
- 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 +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +117 -30
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/null_relation.rb +0 -68
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
|
@@ -6,21 +6,23 @@ require "zlib"
|
|
|
6
6
|
require "set"
|
|
7
7
|
require "active_support/dependencies"
|
|
8
8
|
require "active_support/core_ext/digest/uuid"
|
|
9
|
-
require "active_record/fixture_set/file"
|
|
10
|
-
require "active_record/fixture_set/render_context"
|
|
11
|
-
require "active_record/fixture_set/table_rows"
|
|
12
9
|
require "active_record/test_fixtures"
|
|
13
|
-
require "active_record/errors"
|
|
14
10
|
|
|
15
11
|
module ActiveRecord
|
|
16
|
-
class FixtureClassNotFound < ActiveRecord::ActiveRecordError
|
|
12
|
+
class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
|
|
17
13
|
end
|
|
18
14
|
|
|
15
|
+
# = Active Record \Fixtures
|
|
16
|
+
#
|
|
19
17
|
# \Fixtures are a way of organizing data that you want to test against; in short, sample data.
|
|
20
18
|
#
|
|
21
|
-
# They are stored in YAML files, one file per model, which are placed in
|
|
22
|
-
#
|
|
23
|
-
#
|
|
19
|
+
# They are stored in YAML files, one file per model, which are by default placed in either
|
|
20
|
+
# <tt><your-rails-app>/test/fixtures/</tt> or in the <tt>test/fixtures</tt>
|
|
21
|
+
# folder under any of your application's engines.
|
|
22
|
+
#
|
|
23
|
+
# The location can also be changed with ActiveSupport::TestCase.fixture_paths=,
|
|
24
|
+
# once you have <tt>require "rails/test_help"</tt> in your +test_helper.rb+.
|
|
25
|
+
#
|
|
24
26
|
# The fixture file ends with the +.yml+ file extension, for example:
|
|
25
27
|
# <tt><your-rails-app>/test/fixtures/web_sites.yml</tt>).
|
|
26
28
|
#
|
|
@@ -36,14 +38,21 @@ module ActiveRecord
|
|
|
36
38
|
# name: Google
|
|
37
39
|
# url: http://www.google.com
|
|
38
40
|
#
|
|
39
|
-
# This fixture file includes two fixtures. Each YAML fixture (
|
|
41
|
+
# This fixture file includes two fixtures. Each YAML fixture (i.e. record) is given a name and
|
|
40
42
|
# is followed by an indented list of key/value pairs in the "key: value" format. Records are
|
|
41
43
|
# separated by a blank line for your viewing pleasure.
|
|
42
44
|
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
45
|
+
# == Ordering
|
|
46
|
+
#
|
|
47
|
+
# Fixtures by default are unordered. This is because the maps in YAML are unordered.
|
|
48
|
+
#
|
|
49
|
+
# If you want ordered fixtures, use the omap YAML type.
|
|
50
|
+
# See https://yaml.org/type/omap.html for the specification.
|
|
51
|
+
#
|
|
52
|
+
# You will need ordered fixtures when you have foreign key constraints
|
|
53
|
+
# on keys in the same table. This is commonly needed for tree structures.
|
|
54
|
+
#
|
|
55
|
+
# For example:
|
|
47
56
|
#
|
|
48
57
|
# --- !omap
|
|
49
58
|
# - parent:
|
|
@@ -55,12 +64,12 @@ module ActiveRecord
|
|
|
55
64
|
# parent_id: 1
|
|
56
65
|
# title: Child
|
|
57
66
|
#
|
|
58
|
-
#
|
|
67
|
+
# == Using Fixtures in Test Cases
|
|
59
68
|
#
|
|
60
69
|
# Since fixtures are a testing construct, we use them in our unit and functional tests. There
|
|
61
70
|
# are two ways to use the fixtures, but first let's take a look at a sample unit test:
|
|
62
71
|
#
|
|
63
|
-
# require
|
|
72
|
+
# require "test_helper"
|
|
64
73
|
#
|
|
65
74
|
# class WebSiteTest < ActiveSupport::TestCase
|
|
66
75
|
# test "web_site_count" do
|
|
@@ -101,6 +110,12 @@ module ActiveRecord
|
|
|
101
110
|
# assert_raise(StandardError) { web_sites(:reddit) }
|
|
102
111
|
# end
|
|
103
112
|
#
|
|
113
|
+
# If the model names conflicts with a +TestCase+ methods, you can use the generic +fixture+ accessor
|
|
114
|
+
#
|
|
115
|
+
# test "generic find" do
|
|
116
|
+
# assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
|
|
117
|
+
# end
|
|
118
|
+
#
|
|
104
119
|
# Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the
|
|
105
120
|
# following tests:
|
|
106
121
|
#
|
|
@@ -125,7 +140,7 @@ module ActiveRecord
|
|
|
125
140
|
# traversed in the database to create the fixture hash and/or instance variables. This is expensive for
|
|
126
141
|
# large sets of fixtured data.
|
|
127
142
|
#
|
|
128
|
-
#
|
|
143
|
+
# == Dynamic fixtures with \ERB
|
|
129
144
|
#
|
|
130
145
|
# Sometimes you don't care about the content of the fixtures as much as you care about the volume.
|
|
131
146
|
# In these cases, you can mix ERB in with your YAML fixtures to create a bunch of fixtures for load
|
|
@@ -153,7 +168,7 @@ module ActiveRecord
|
|
|
153
168
|
# - define a helper method in <tt>test_helper.rb</tt>
|
|
154
169
|
# module FixtureFileHelpers
|
|
155
170
|
# def file_sha(path)
|
|
156
|
-
# Digest::
|
|
171
|
+
# OpenSSL::Digest::SHA256.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
|
|
157
172
|
# end
|
|
158
173
|
# end
|
|
159
174
|
# ActiveRecord::FixtureSet.context_class.include FixtureFileHelpers
|
|
@@ -163,7 +178,7 @@ module ActiveRecord
|
|
|
163
178
|
# name: kitten.png
|
|
164
179
|
# sha: <%= file_sha 'files/kitten.png' %>
|
|
165
180
|
#
|
|
166
|
-
#
|
|
181
|
+
# == Transactional Tests
|
|
167
182
|
#
|
|
168
183
|
# Test cases can use begin+rollback to isolate their changes to the database instead of having to
|
|
169
184
|
# delete+insert for every test case.
|
|
@@ -182,7 +197,7 @@ module ActiveRecord
|
|
|
182
197
|
# end
|
|
183
198
|
# end
|
|
184
199
|
#
|
|
185
|
-
# If you preload your test database with all fixture data (probably by running
|
|
200
|
+
# If you preload your test database with all fixture data (probably by running <tt>bin/rails db:fixtures:load</tt>)
|
|
186
201
|
# and use transactional tests, then you may omit all fixtures declarations in your test cases since
|
|
187
202
|
# all the data's already there and every case rolls back its changes.
|
|
188
203
|
#
|
|
@@ -199,7 +214,7 @@ module ActiveRecord
|
|
|
199
214
|
# 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM.
|
|
200
215
|
# Use InnoDB, MaxDB, or NDB instead.
|
|
201
216
|
#
|
|
202
|
-
#
|
|
217
|
+
# == Advanced Fixtures
|
|
203
218
|
#
|
|
204
219
|
# Fixtures that don't specify an ID get some extra features:
|
|
205
220
|
#
|
|
@@ -213,7 +228,7 @@ module ActiveRecord
|
|
|
213
228
|
# * Fixture label interpolation
|
|
214
229
|
# * Support for YAML defaults
|
|
215
230
|
#
|
|
216
|
-
#
|
|
231
|
+
# === Stable, Autogenerated IDs
|
|
217
232
|
#
|
|
218
233
|
# Here, have a monkey fixture:
|
|
219
234
|
#
|
|
@@ -242,13 +257,13 @@ module ActiveRecord
|
|
|
242
257
|
# The generated ID for a given label is constant, so we can discover
|
|
243
258
|
# any fixture's ID without loading anything, as long as we know the label.
|
|
244
259
|
#
|
|
245
|
-
#
|
|
260
|
+
# === Label references for associations (+belongs_to+, +has_one+, +has_many+)
|
|
246
261
|
#
|
|
247
262
|
# Specifying foreign keys in fixtures can be very fragile, not to
|
|
248
263
|
# mention difficult to read. Since Active Record can figure out the ID of
|
|
249
264
|
# any fixture from its label, you can specify FK's by label instead of ID.
|
|
250
265
|
#
|
|
251
|
-
#
|
|
266
|
+
# ==== +belongs_to+
|
|
252
267
|
#
|
|
253
268
|
# Let's break out some more monkeys and pirates.
|
|
254
269
|
#
|
|
@@ -259,6 +274,8 @@ module ActiveRecord
|
|
|
259
274
|
# name: Reginald the Pirate
|
|
260
275
|
# monkey_id: 1
|
|
261
276
|
#
|
|
277
|
+
# <code></code>
|
|
278
|
+
#
|
|
262
279
|
# ### in monkeys.yml
|
|
263
280
|
#
|
|
264
281
|
# george:
|
|
@@ -276,6 +293,8 @@ module ActiveRecord
|
|
|
276
293
|
# name: Reginald the Pirate
|
|
277
294
|
# monkey: george
|
|
278
295
|
#
|
|
296
|
+
# <code></code>
|
|
297
|
+
#
|
|
279
298
|
# ### in monkeys.yml
|
|
280
299
|
#
|
|
281
300
|
# george:
|
|
@@ -287,7 +306,7 @@ module ActiveRecord
|
|
|
287
306
|
# a target *label* for the *association* (monkey: george) rather than
|
|
288
307
|
# a target *id* for the *FK* (<tt>monkey_id: 1</tt>).
|
|
289
308
|
#
|
|
290
|
-
# ==== Polymorphic belongs_to
|
|
309
|
+
# ==== Polymorphic +belongs_to+
|
|
291
310
|
#
|
|
292
311
|
# Supporting polymorphic relationships is a little bit more complicated, since
|
|
293
312
|
# Active Record needs to know what type your association is pointing at. Something
|
|
@@ -297,6 +316,8 @@ module ActiveRecord
|
|
|
297
316
|
#
|
|
298
317
|
# belongs_to :eater, polymorphic: true
|
|
299
318
|
#
|
|
319
|
+
# <code></code>
|
|
320
|
+
#
|
|
300
321
|
# ### in fruits.yml
|
|
301
322
|
#
|
|
302
323
|
# apple:
|
|
@@ -312,9 +333,9 @@ module ActiveRecord
|
|
|
312
333
|
#
|
|
313
334
|
# Just provide the polymorphic target type and Active Record will take care of the rest.
|
|
314
335
|
#
|
|
315
|
-
#
|
|
336
|
+
# ==== +has_and_belongs_to_many+ or <tt>has_many :through</tt>
|
|
316
337
|
#
|
|
317
|
-
# Time to give our monkey some fruit.
|
|
338
|
+
# \Time to give our monkey some fruit.
|
|
318
339
|
#
|
|
319
340
|
# ### in monkeys.yml
|
|
320
341
|
#
|
|
@@ -322,6 +343,8 @@ module ActiveRecord
|
|
|
322
343
|
# id: 1
|
|
323
344
|
# name: George the Monkey
|
|
324
345
|
#
|
|
346
|
+
# <code></code>
|
|
347
|
+
#
|
|
325
348
|
# ### in fruits.yml
|
|
326
349
|
#
|
|
327
350
|
# apple:
|
|
@@ -336,6 +359,8 @@ module ActiveRecord
|
|
|
336
359
|
# id: 3
|
|
337
360
|
# name: grape
|
|
338
361
|
#
|
|
362
|
+
# <code></code>
|
|
363
|
+
#
|
|
339
364
|
# ### in fruits_monkeys.yml
|
|
340
365
|
#
|
|
341
366
|
# apple_george:
|
|
@@ -359,6 +384,8 @@ module ActiveRecord
|
|
|
359
384
|
# name: George the Monkey
|
|
360
385
|
# fruits: apple, orange, grape
|
|
361
386
|
#
|
|
387
|
+
# <code></code>
|
|
388
|
+
#
|
|
362
389
|
# ### in fruits.yml
|
|
363
390
|
#
|
|
364
391
|
# apple:
|
|
@@ -376,7 +403,7 @@ module ActiveRecord
|
|
|
376
403
|
# the fixture's model class and discovers the +has_and_belongs_to_many+
|
|
377
404
|
# associations.
|
|
378
405
|
#
|
|
379
|
-
#
|
|
406
|
+
# === Autofilled \Timestamp Columns
|
|
380
407
|
#
|
|
381
408
|
# If your table/model specifies any of Active Record's
|
|
382
409
|
# standard timestamp columns (+created_at+, +created_on+, +updated_at+, +updated_on+),
|
|
@@ -384,7 +411,7 @@ module ActiveRecord
|
|
|
384
411
|
#
|
|
385
412
|
# If you've set specific values, they'll be left alone.
|
|
386
413
|
#
|
|
387
|
-
#
|
|
414
|
+
# === Fixture label interpolation
|
|
388
415
|
#
|
|
389
416
|
# The label of the current fixture is always available as a column value:
|
|
390
417
|
#
|
|
@@ -401,14 +428,18 @@ module ActiveRecord
|
|
|
401
428
|
# monkey_id: <%= ActiveRecord::FixtureSet.identify(:reginald) %>
|
|
402
429
|
# pirate_id: <%= ActiveRecord::FixtureSet.identify(:george) %>
|
|
403
430
|
#
|
|
404
|
-
#
|
|
431
|
+
# If the model uses UUID values for identifiers, add the +:uuid+ argument:
|
|
432
|
+
#
|
|
433
|
+
# ActiveRecord::FixtureSet.identify(:boaty_mcboatface, :uuid)
|
|
434
|
+
#
|
|
435
|
+
# === Support for YAML defaults
|
|
405
436
|
#
|
|
406
437
|
# You can set and reuse defaults in your fixtures YAML file.
|
|
407
438
|
# This is the same technique used in the +database.yml+ file to specify
|
|
408
439
|
# defaults:
|
|
409
440
|
#
|
|
410
441
|
# DEFAULTS: &DEFAULTS
|
|
411
|
-
# created_on: <%= 3.weeks.ago.
|
|
442
|
+
# created_on: <%= 3.weeks.ago.to_fs(:db) %>
|
|
412
443
|
#
|
|
413
444
|
# first:
|
|
414
445
|
# name: Smurf
|
|
@@ -420,12 +451,74 @@ module ActiveRecord
|
|
|
420
451
|
#
|
|
421
452
|
# Any fixture labeled "DEFAULTS" is safely ignored.
|
|
422
453
|
#
|
|
454
|
+
# Besides using "DEFAULTS", you can also specify what fixtures will
|
|
455
|
+
# be ignored by setting "ignore" in "_fixture" section.
|
|
456
|
+
#
|
|
457
|
+
# # users.yml
|
|
458
|
+
# _fixture:
|
|
459
|
+
# ignore:
|
|
460
|
+
# - base
|
|
461
|
+
# # or use "ignore: base" when there is only one fixture that needs to be ignored.
|
|
462
|
+
#
|
|
463
|
+
# base: &base
|
|
464
|
+
# admin: false
|
|
465
|
+
# introduction: "This is a default description"
|
|
466
|
+
#
|
|
467
|
+
# admin:
|
|
468
|
+
# <<: *base
|
|
469
|
+
# admin: true
|
|
470
|
+
#
|
|
471
|
+
# visitor:
|
|
472
|
+
# <<: *base
|
|
473
|
+
#
|
|
474
|
+
# In the above example, 'base' will be ignored when creating fixtures.
|
|
475
|
+
# This can be used for common attributes inheriting.
|
|
476
|
+
#
|
|
477
|
+
# == Composite Primary Key Fixtures
|
|
478
|
+
#
|
|
479
|
+
# Fixtures for composite primary key tables are fairly similar to normal tables.
|
|
480
|
+
# When using an id column, the column may be omitted as usual:
|
|
481
|
+
#
|
|
482
|
+
# # app/models/book.rb
|
|
483
|
+
# class Book < ApplicationRecord
|
|
484
|
+
# self.primary_key = [:author_id, :id]
|
|
485
|
+
# belongs_to :author
|
|
486
|
+
# end
|
|
487
|
+
#
|
|
488
|
+
# <code></code>
|
|
489
|
+
#
|
|
490
|
+
# # books.yml
|
|
491
|
+
# alices_adventure_in_wonderland:
|
|
492
|
+
# author_id: <%= ActiveRecord::FixtureSet.identify(:lewis_carroll) %>
|
|
493
|
+
# title: "Alice's Adventures in Wonderland"
|
|
494
|
+
#
|
|
495
|
+
# However, in order to support composite primary key relationships,
|
|
496
|
+
# you must use the `composite_identify` method:
|
|
497
|
+
#
|
|
498
|
+
# # app/models/book_orders.rb
|
|
499
|
+
# class BookOrder < ApplicationRecord
|
|
500
|
+
# self.primary_key = [:shop_id, :id]
|
|
501
|
+
# belongs_to :order, foreign_key: [:shop_id, :order_id]
|
|
502
|
+
# belongs_to :book, foreign_key: [:author_id, :book_id]
|
|
503
|
+
# end
|
|
504
|
+
#
|
|
505
|
+
# <code></code>
|
|
506
|
+
#
|
|
507
|
+
# # book_orders.yml
|
|
508
|
+
# alices_adventure_in_wonderland_in_books:
|
|
509
|
+
# author: lewis_carroll
|
|
510
|
+
# book_id: <%= ActiveRecord::FixtureSet.composite_identify(
|
|
511
|
+
# :alices_adventure_in_wonderland, Book.primary_key)[:id] %>
|
|
512
|
+
# shop: book_store
|
|
513
|
+
# order_id: <%= ActiveRecord::FixtureSet.composite_identify(
|
|
514
|
+
# :books, Order.primary_key)[:id] %>
|
|
515
|
+
#
|
|
423
516
|
# == Configure the fixture model class
|
|
424
517
|
#
|
|
425
518
|
# It's possible to set the fixture's model class directly in the YAML file.
|
|
426
519
|
# This is helpful when fixtures are loaded outside tests and
|
|
427
520
|
# +set_fixture_class+ is not available (e.g.
|
|
428
|
-
# when running <tt>rails db:fixtures:load</tt>).
|
|
521
|
+
# when running <tt>bin/rails db:fixtures:load</tt>).
|
|
429
522
|
#
|
|
430
523
|
# _fixture:
|
|
431
524
|
# model_class: User
|
|
@@ -434,6 +527,10 @@ module ActiveRecord
|
|
|
434
527
|
#
|
|
435
528
|
# Any fixtures labeled "_fixture" are safely ignored.
|
|
436
529
|
class FixtureSet
|
|
530
|
+
require "active_record/fixture_set/file"
|
|
531
|
+
require "active_record/fixture_set/render_context"
|
|
532
|
+
require "active_record/fixture_set/table_rows"
|
|
533
|
+
|
|
437
534
|
#--
|
|
438
535
|
# An instance of FixtureSet is normally stored in a single YAML file and
|
|
439
536
|
# possibly in a folder with the same name.
|
|
@@ -445,40 +542,6 @@ module ActiveRecord
|
|
|
445
542
|
|
|
446
543
|
cattr_accessor :all_loaded_fixtures, default: {}
|
|
447
544
|
|
|
448
|
-
class ClassCache
|
|
449
|
-
def initialize(class_names, config)
|
|
450
|
-
@class_names = class_names.stringify_keys
|
|
451
|
-
@config = config
|
|
452
|
-
|
|
453
|
-
# Remove string values that aren't constants or subclasses of AR
|
|
454
|
-
@class_names.delete_if do |klass_name, klass|
|
|
455
|
-
!insert_class(@class_names, klass_name, klass)
|
|
456
|
-
end
|
|
457
|
-
end
|
|
458
|
-
|
|
459
|
-
def [](fs_name)
|
|
460
|
-
@class_names.fetch(fs_name) do
|
|
461
|
-
klass = default_fixture_model(fs_name, @config).safe_constantize
|
|
462
|
-
insert_class(@class_names, fs_name, klass)
|
|
463
|
-
end
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
private
|
|
467
|
-
|
|
468
|
-
def insert_class(class_names, name, klass)
|
|
469
|
-
# We only want to deal with AR objects.
|
|
470
|
-
if klass && klass < ActiveRecord::Base
|
|
471
|
-
class_names[name] = klass
|
|
472
|
-
else
|
|
473
|
-
class_names[name] = nil
|
|
474
|
-
end
|
|
475
|
-
end
|
|
476
|
-
|
|
477
|
-
def default_fixture_model(fs_name, config)
|
|
478
|
-
ActiveRecord::FixtureSet.default_fixture_model_name(fs_name, config)
|
|
479
|
-
end
|
|
480
|
-
end
|
|
481
|
-
|
|
482
545
|
class << self
|
|
483
546
|
def default_fixture_model_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc:
|
|
484
547
|
config.pluralize_table_names ?
|
|
@@ -496,24 +559,24 @@ module ActiveRecord
|
|
|
496
559
|
@@all_cached_fixtures.clear
|
|
497
560
|
end
|
|
498
561
|
|
|
499
|
-
def
|
|
500
|
-
@@all_cached_fixtures[
|
|
562
|
+
def cache_for_connection_pool(connection_pool)
|
|
563
|
+
@@all_cached_fixtures[connection_pool]
|
|
501
564
|
end
|
|
502
565
|
|
|
503
|
-
def fixture_is_cached?(
|
|
504
|
-
|
|
566
|
+
def fixture_is_cached?(connection_pool, table_name)
|
|
567
|
+
cache_for_connection_pool(connection_pool)[table_name]
|
|
505
568
|
end
|
|
506
569
|
|
|
507
|
-
def cached_fixtures(
|
|
570
|
+
def cached_fixtures(connection_pool, keys_to_fetch = nil)
|
|
508
571
|
if keys_to_fetch
|
|
509
|
-
|
|
572
|
+
cache_for_connection_pool(connection_pool).values_at(*keys_to_fetch)
|
|
510
573
|
else
|
|
511
|
-
|
|
574
|
+
cache_for_connection_pool(connection_pool).values
|
|
512
575
|
end
|
|
513
576
|
end
|
|
514
577
|
|
|
515
|
-
def cache_fixtures(
|
|
516
|
-
|
|
578
|
+
def cache_fixtures(connection_pool, fixtures_map)
|
|
579
|
+
cache_for_connection_pool(connection_pool).update(fixtures_map)
|
|
517
580
|
end
|
|
518
581
|
|
|
519
582
|
def instantiate_fixtures(object, fixture_set, load_instances = true)
|
|
@@ -531,31 +594,30 @@ module ActiveRecord
|
|
|
531
594
|
end
|
|
532
595
|
end
|
|
533
596
|
|
|
534
|
-
def create_fixtures(
|
|
597
|
+
def create_fixtures(fixtures_directories, fixture_set_names, class_names = {}, config = ActiveRecord::Base)
|
|
535
598
|
fixture_set_names = Array(fixture_set_names).map(&:to_s)
|
|
536
|
-
class_names
|
|
537
|
-
|
|
538
|
-
# FIXME: Apparently JK uses this.
|
|
539
|
-
connection = block_given? ? block : lambda { ActiveRecord::Base.connection }
|
|
599
|
+
class_names.stringify_keys!
|
|
540
600
|
|
|
601
|
+
connection_pool = config.connection_pool
|
|
541
602
|
fixture_files_to_read = fixture_set_names.reject do |fs_name|
|
|
542
|
-
fixture_is_cached?(
|
|
603
|
+
fixture_is_cached?(connection_pool, fs_name)
|
|
543
604
|
end
|
|
544
605
|
|
|
545
606
|
if fixture_files_to_read.any?
|
|
546
607
|
fixtures_map = read_and_insert(
|
|
547
|
-
|
|
608
|
+
Array(fixtures_directories),
|
|
548
609
|
fixture_files_to_read,
|
|
549
610
|
class_names,
|
|
550
|
-
|
|
611
|
+
connection_pool,
|
|
551
612
|
)
|
|
552
|
-
cache_fixtures(
|
|
613
|
+
cache_fixtures(connection_pool, fixtures_map)
|
|
553
614
|
end
|
|
554
|
-
cached_fixtures(
|
|
615
|
+
cached_fixtures(connection_pool, fixture_set_names)
|
|
555
616
|
end
|
|
556
617
|
|
|
557
618
|
# Returns a consistent, platform-independent identifier for +label+.
|
|
558
|
-
#
|
|
619
|
+
#
|
|
620
|
+
# \Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes.
|
|
559
621
|
def identify(label, column_type = :integer)
|
|
560
622
|
if column_type == :uuid
|
|
561
623
|
Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, label.to_s)
|
|
@@ -564,41 +626,54 @@ module ActiveRecord
|
|
|
564
626
|
end
|
|
565
627
|
end
|
|
566
628
|
|
|
567
|
-
#
|
|
629
|
+
# Returns a consistent, platform-independent hash representing a mapping
|
|
630
|
+
# between the label and the subcomponents of the provided composite key.
|
|
631
|
+
#
|
|
632
|
+
# Example:
|
|
633
|
+
#
|
|
634
|
+
# composite_identify("label", [:a, :b, :c]) # => { a: hash_1, b: hash_2, c: hash_3 }
|
|
635
|
+
def composite_identify(label, key)
|
|
636
|
+
key
|
|
637
|
+
.index_with
|
|
638
|
+
.with_index { |sub_key, index| (identify(label) << index) % MAX_ID }
|
|
639
|
+
.with_indifferent_access
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
# Superclass for the evaluation contexts used by \ERB fixtures.
|
|
568
643
|
def context_class
|
|
569
644
|
@context_class ||= Class.new
|
|
570
645
|
end
|
|
571
646
|
|
|
572
647
|
private
|
|
573
|
-
|
|
574
|
-
def read_and_insert(fixtures_directory, fixture_files, class_names, connection) # :nodoc:
|
|
648
|
+
def read_and_insert(fixtures_directories, fixture_files, class_names, connection_pool) # :nodoc:
|
|
575
649
|
fixtures_map = {}
|
|
650
|
+
directory_glob = "{#{fixtures_directories.join(",")}}"
|
|
576
651
|
fixture_sets = fixture_files.map do |fixture_set_name|
|
|
577
652
|
klass = class_names[fixture_set_name]
|
|
578
653
|
fixtures_map[fixture_set_name] = new( # ActiveRecord::FixtureSet.new
|
|
579
654
|
nil,
|
|
580
655
|
fixture_set_name,
|
|
581
656
|
klass,
|
|
582
|
-
::File.join(
|
|
657
|
+
::File.join(directory_glob, fixture_set_name)
|
|
583
658
|
)
|
|
584
659
|
end
|
|
585
660
|
update_all_loaded_fixtures(fixtures_map)
|
|
586
661
|
|
|
587
|
-
insert(fixture_sets,
|
|
662
|
+
insert(fixture_sets, connection_pool)
|
|
588
663
|
|
|
589
664
|
fixtures_map
|
|
590
665
|
end
|
|
591
666
|
|
|
592
|
-
def insert(fixture_sets,
|
|
593
|
-
|
|
667
|
+
def insert(fixture_sets, connection_pool) # :nodoc:
|
|
668
|
+
fixture_sets_by_pool = fixture_sets.group_by do |fixture_set|
|
|
594
669
|
if fixture_set.model_class
|
|
595
|
-
fixture_set.model_class.
|
|
670
|
+
fixture_set.model_class.connection_pool
|
|
596
671
|
else
|
|
597
|
-
|
|
672
|
+
connection_pool
|
|
598
673
|
end
|
|
599
674
|
end
|
|
600
675
|
|
|
601
|
-
|
|
676
|
+
fixture_sets_by_pool.each do |pool, set|
|
|
602
677
|
table_rows_for_connection = Hash.new { |h, k| h[k] = [] }
|
|
603
678
|
|
|
604
679
|
set.each do |fixture_set|
|
|
@@ -607,21 +682,35 @@ module ActiveRecord
|
|
|
607
682
|
end
|
|
608
683
|
end
|
|
609
684
|
|
|
610
|
-
|
|
685
|
+
pool.with_connection do |conn|
|
|
686
|
+
conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys)
|
|
687
|
+
|
|
688
|
+
check_all_foreign_keys_valid!(conn)
|
|
611
689
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
690
|
+
# Cap primary key sequences to max(pk).
|
|
691
|
+
if conn.respond_to?(:reset_pk_sequence!)
|
|
692
|
+
set.each { |fs| conn.reset_pk_sequence!(fs.table_name) }
|
|
693
|
+
end
|
|
615
694
|
end
|
|
616
695
|
end
|
|
617
696
|
end
|
|
618
697
|
|
|
698
|
+
def check_all_foreign_keys_valid!(conn)
|
|
699
|
+
return unless ActiveRecord.verify_foreign_keys_for_fixtures
|
|
700
|
+
|
|
701
|
+
begin
|
|
702
|
+
conn.check_all_foreign_keys_valid!
|
|
703
|
+
rescue ActiveRecord::StatementInvalid => e
|
|
704
|
+
raise "Foreign key violations found in your fixture data. Ensure you aren't referring to labels that don't exist on associations. Error from database:\n\n#{e.message}"
|
|
705
|
+
end
|
|
706
|
+
end
|
|
707
|
+
|
|
619
708
|
def update_all_loaded_fixtures(fixtures_map) # :nodoc:
|
|
620
709
|
all_loaded_fixtures.update(fixtures_map)
|
|
621
710
|
end
|
|
622
711
|
end
|
|
623
712
|
|
|
624
|
-
attr_reader :table_name, :name, :fixtures, :model_class, :config
|
|
713
|
+
attr_reader :table_name, :name, :fixtures, :model_class, :ignored_fixtures, :config
|
|
625
714
|
|
|
626
715
|
def initialize(_, name, class_name, path, config = ActiveRecord::Base)
|
|
627
716
|
@name = name
|
|
@@ -629,7 +718,6 @@ module ActiveRecord
|
|
|
629
718
|
@config = config
|
|
630
719
|
|
|
631
720
|
self.model_class = class_name
|
|
632
|
-
|
|
633
721
|
@fixtures = read_fixture_files(path)
|
|
634
722
|
|
|
635
723
|
@table_name = model_class&.table_name || self.class.default_fixture_table_name(name, config)
|
|
@@ -654,19 +742,17 @@ module ActiveRecord
|
|
|
654
742
|
# Returns a hash of rows to be inserted. The key is the table, the value is
|
|
655
743
|
# a list of rows to insert to that table.
|
|
656
744
|
def table_rows
|
|
657
|
-
# allow
|
|
658
|
-
fixtures.
|
|
745
|
+
# allow specifying fixtures to be ignored by setting `ignore` in `_fixture` section
|
|
746
|
+
fixtures.except!(*ignored_fixtures)
|
|
659
747
|
|
|
660
748
|
TableRows.new(
|
|
661
749
|
table_name,
|
|
662
750
|
model_class: model_class,
|
|
663
751
|
fixtures: fixtures,
|
|
664
|
-
config: config,
|
|
665
752
|
).to_hash
|
|
666
753
|
end
|
|
667
754
|
|
|
668
755
|
private
|
|
669
|
-
|
|
670
756
|
def model_class=(class_name)
|
|
671
757
|
if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
|
|
672
758
|
@model_class = class_name
|
|
@@ -675,17 +761,37 @@ module ActiveRecord
|
|
|
675
761
|
end
|
|
676
762
|
end
|
|
677
763
|
|
|
764
|
+
def ignored_fixtures=(base)
|
|
765
|
+
@ignored_fixtures =
|
|
766
|
+
case base
|
|
767
|
+
when Array
|
|
768
|
+
base
|
|
769
|
+
when String
|
|
770
|
+
[base]
|
|
771
|
+
else
|
|
772
|
+
[]
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
@ignored_fixtures << "DEFAULTS" unless @ignored_fixtures.include?("DEFAULTS")
|
|
776
|
+
@ignored_fixtures.compact
|
|
777
|
+
end
|
|
778
|
+
|
|
678
779
|
# Loads the fixtures from the YAML file at +path+.
|
|
679
780
|
# If the file sets the +model_class+ and current instance value is not set,
|
|
680
781
|
# it uses the file value.
|
|
782
|
+
|
|
681
783
|
def read_fixture_files(path)
|
|
682
|
-
yaml_files = Dir["#{path}
|
|
784
|
+
yaml_files = Dir["#{path}{.yml,/{**,*}/*.yml}"].select { |f|
|
|
683
785
|
::File.file?(f)
|
|
684
|
-
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
raise ArgumentError, "No fixture files found for #{@name}" if yaml_files.empty?
|
|
685
789
|
|
|
686
790
|
yaml_files.each_with_object({}) do |file, fixtures|
|
|
687
791
|
FixtureSet::File.open(file) do |fh|
|
|
688
792
|
self.model_class ||= fh.model_class if fh.model_class
|
|
793
|
+
self.model_class ||= default_fixture_model_class
|
|
794
|
+
self.ignored_fixtures ||= fh.ignored_fixtures
|
|
689
795
|
fh.each do |fixture_name, row|
|
|
690
796
|
fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
|
|
691
797
|
end
|
|
@@ -693,18 +799,19 @@ module ActiveRecord
|
|
|
693
799
|
end
|
|
694
800
|
end
|
|
695
801
|
|
|
696
|
-
def
|
|
697
|
-
|
|
802
|
+
def default_fixture_model_class
|
|
803
|
+
klass = ActiveRecord::FixtureSet.default_fixture_model_name(@name, @config).safe_constantize
|
|
804
|
+
klass if klass && klass < ActiveRecord::Base
|
|
698
805
|
end
|
|
699
806
|
end
|
|
700
807
|
|
|
701
|
-
class Fixture
|
|
808
|
+
class Fixture # :nodoc:
|
|
702
809
|
include Enumerable
|
|
703
810
|
|
|
704
|
-
class FixtureError < StandardError
|
|
811
|
+
class FixtureError < StandardError # :nodoc:
|
|
705
812
|
end
|
|
706
813
|
|
|
707
|
-
class FormatError < FixtureError
|
|
814
|
+
class FormatError < FixtureError # :nodoc:
|
|
708
815
|
end
|
|
709
816
|
|
|
710
817
|
attr_reader :model_class, :fixture
|
|
@@ -718,8 +825,8 @@ module ActiveRecord
|
|
|
718
825
|
model_class.name if model_class
|
|
719
826
|
end
|
|
720
827
|
|
|
721
|
-
def each
|
|
722
|
-
fixture.each
|
|
828
|
+
def each(&block)
|
|
829
|
+
fixture.each(&block)
|
|
723
830
|
end
|
|
724
831
|
|
|
725
832
|
def [](key)
|
|
@@ -730,9 +837,15 @@ module ActiveRecord
|
|
|
730
837
|
|
|
731
838
|
def find
|
|
732
839
|
raise FixtureClassNotFound, "No class attached to find." unless model_class
|
|
733
|
-
model_class.unscoped do
|
|
734
|
-
|
|
840
|
+
object = model_class.unscoped do
|
|
841
|
+
pk_clauses = fixture.slice(*Array(model_class.primary_key))
|
|
842
|
+
model_class.find_by!(pk_clauses)
|
|
735
843
|
end
|
|
844
|
+
# Fixtures can't be eagerly loaded
|
|
845
|
+
object.instance_variable_set(:@strict_loading, false)
|
|
846
|
+
object
|
|
736
847
|
end
|
|
737
848
|
end
|
|
738
849
|
end
|
|
850
|
+
|
|
851
|
+
ActiveSupport.run_load_hooks :active_record_fixture_set, ActiveRecord::FixtureSet
|