activerecord 5.0.6 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +638 -2023
- data/MIT-LICENSE +3 -1
- data/README.rdoc +8 -6
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record/aggregations.rb +249 -246
- data/lib/active_record/association_relation.rb +24 -13
- data/lib/active_record/associations/alias_tracker.rb +24 -33
- data/lib/active_record/associations/association.rb +119 -56
- data/lib/active_record/associations/association_scope.rb +94 -94
- data/lib/active_record/associations/belongs_to_association.rb +58 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +18 -25
- data/lib/active_record/associations/builder/belongs_to.rb +43 -54
- data/lib/active_record/associations/builder/collection_association.rb +7 -18
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
- data/lib/active_record/associations/builder/has_many.rb +4 -0
- data/lib/active_record/associations/builder/has_one.rb +37 -1
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +80 -252
- data/lib/active_record/associations/collection_proxy.rb +158 -121
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -29
- data/lib/active_record/associations/has_many_through_association.rb +58 -44
- data/lib/active_record/associations/has_one_association.rb +59 -54
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +134 -176
- data/lib/active_record/associations/preloader/association.rb +84 -125
- data/lib/active_record/associations/preloader/through_association.rb +82 -75
- data/lib/active_record/associations/preloader.rb +90 -102
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +26 -14
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/attribute_assignment.rb +54 -60
- data/lib/active_record/attribute_decorators.rb +38 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +86 -91
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +21 -49
- data/lib/active_record/attribute_methods/serialization.rb +30 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
- data/lib/active_record/attribute_methods/write.rb +35 -33
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attributes.rb +38 -24
- data/lib/active_record/autosave_association.rb +53 -32
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +63 -33
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -11
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
- data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
- data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
- data/lib/active_record/connection_handling.rb +159 -40
- data/lib/active_record/core.rb +202 -162
- data/lib/active_record/counter_cache.rb +57 -28
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +79 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -86
- data/lib/active_record/enum.rb +60 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -3
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +13 -8
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +195 -502
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +151 -97
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +15 -18
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +78 -87
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +48 -29
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +143 -97
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +367 -300
- data/lib/active_record/model_schema.rb +145 -139
- data/lib/active_record/nested_attributes.rb +214 -201
- data/lib/active_record/no_touching.rb +10 -1
- data/lib/active_record/null_relation.rb +13 -34
- data/lib/active_record/persistence.rb +442 -72
- data/lib/active_record/query_cache.rb +15 -14
- data/lib/active_record/querying.rb +36 -23
- data/lib/active_record/railtie.rb +128 -36
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +309 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +211 -249
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/batches.rb +99 -52
- data/lib/active_record/relation/calculations.rb +211 -172
- data/lib/active_record/relation/delegation.rb +67 -65
- data/lib/active_record/relation/finder_methods.rb +208 -247
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +78 -61
- data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +86 -104
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +458 -329
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -7
- data/lib/active_record/relation/where_clause.rb +111 -95
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/relation.rb +429 -318
- data/lib/active_record/result.rb +69 -39
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +83 -99
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +71 -69
- data/lib/active_record/schema_migration.rb +15 -5
- data/lib/active_record/scoping/default.rb +93 -95
- data/lib/active_record/scoping/named.rb +45 -25
- data/lib/active_record/scoping.rb +20 -19
- data/lib/active_record/secure_token.rb +4 -2
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +63 -28
- data/lib/active_record/store.rb +121 -41
- data/lib/active_record/suppressor.rb +4 -1
- data/lib/active_record/table_metadata.rb +26 -20
- data/lib/active_record/tasks/database_tasks.rb +276 -85
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
- data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +70 -35
- data/lib/active_record/touch_later.rb +7 -4
- data/lib/active_record/transactions.rb +133 -149
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +44 -45
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +16 -8
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +2 -1
- data/lib/active_record/type/type_map.rb +13 -15
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +23 -17
- data/lib/active_record/type_caster/connection.rb +17 -12
- data/lib/active_record/type_caster/map.rb +5 -4
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +3 -1
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +29 -42
- data/lib/active_record/validations.rb +7 -4
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -22
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -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/insert_manager.rb +49 -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 +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -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 +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -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 +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -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 +41 -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 +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +58 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
- data/lib/rails/generators/active_record/migration.rb +17 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +133 -50
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -20
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set/builder.rb +0 -130
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,11 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "yaml"
|
5
|
+
require "zlib"
|
6
|
+
require "set"
|
7
|
+
require "active_support/dependencies"
|
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
|
+
require "active_record/test_fixtures"
|
13
|
+
require "active_record/errors"
|
9
14
|
|
10
15
|
module ActiveRecord
|
11
16
|
class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc:
|
@@ -66,17 +71,36 @@ module ActiveRecord
|
|
66
71
|
# By default, +test_helper.rb+ will load all of your fixtures into your test
|
67
72
|
# database, so this test will succeed.
|
68
73
|
#
|
69
|
-
# The testing environment will automatically load the
|
74
|
+
# The testing environment will automatically load all the fixtures into the database before each
|
70
75
|
# test. To ensure consistent data, the environment deletes the fixtures before running the load.
|
71
76
|
#
|
72
77
|
# In addition to being available in the database, the fixture's data may also be accessed by
|
73
|
-
# using a special dynamic method, which has the same name as the model
|
74
|
-
# name of the fixture to instantiate:
|
78
|
+
# using a special dynamic method, which has the same name as the model.
|
75
79
|
#
|
76
|
-
#
|
80
|
+
# Passing in a fixture name to this dynamic method returns the fixture matching this name:
|
81
|
+
#
|
82
|
+
# test "find one" do
|
77
83
|
# assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
|
78
84
|
# end
|
79
85
|
#
|
86
|
+
# Passing in multiple fixture names returns all fixtures matching these names:
|
87
|
+
#
|
88
|
+
# test "find all by name" do
|
89
|
+
# assert_equal 2, web_sites(:rubyonrails, :google).length
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# Passing in no arguments returns all fixtures:
|
93
|
+
#
|
94
|
+
# test "find all" do
|
95
|
+
# assert_equal 2, web_sites.length
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
# Passing in any fixture name that does not exist will raise <tt>StandardError</tt>:
|
99
|
+
#
|
100
|
+
# test "find by name that does not exist" do
|
101
|
+
# assert_raise(StandardError) { web_sites(:reddit) }
|
102
|
+
# end
|
103
|
+
#
|
80
104
|
# Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the
|
81
105
|
# following tests:
|
82
106
|
#
|
@@ -88,7 +112,7 @@ module ActiveRecord
|
|
88
112
|
# assert_equal "Ruby on Rails", @rubyonrails.name
|
89
113
|
# end
|
90
114
|
#
|
91
|
-
# In order to use these methods to access fixtured data within your
|
115
|
+
# In order to use these methods to access fixtured data within your test cases, you must specify one of the
|
92
116
|
# following in your ActiveSupport::TestCase-derived class:
|
93
117
|
#
|
94
118
|
# - to fully enable instantiated fixtures (enable alternate methods #1 and #2 above)
|
@@ -103,7 +127,7 @@ module ActiveRecord
|
|
103
127
|
#
|
104
128
|
# = Dynamic fixtures with ERB
|
105
129
|
#
|
106
|
-
#
|
130
|
+
# Sometimes you don't care about the content of the fixtures as much as you care about the volume.
|
107
131
|
# In these cases, you can mix ERB in with your YAML fixtures to create a bunch of fixtures for load
|
108
132
|
# testing, like:
|
109
133
|
#
|
@@ -126,7 +150,7 @@ module ActiveRecord
|
|
126
150
|
# unwanted inter-test dependencies. Methods used by multiple fixtures should be defined in a module
|
127
151
|
# that is included in ActiveRecord::FixtureSet.context_class.
|
128
152
|
#
|
129
|
-
# - define a helper method in
|
153
|
+
# - define a helper method in <tt>test_helper.rb</tt>
|
130
154
|
# module FixtureFileHelpers
|
131
155
|
# def file_sha(path)
|
132
156
|
# Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
|
@@ -148,18 +172,18 @@ module ActiveRecord
|
|
148
172
|
# self.use_transactional_tests = true
|
149
173
|
#
|
150
174
|
# test "godzilla" do
|
151
|
-
#
|
175
|
+
# assert_not_empty Foo.all
|
152
176
|
# Foo.destroy_all
|
153
|
-
#
|
177
|
+
# assert_empty Foo.all
|
154
178
|
# end
|
155
179
|
#
|
156
180
|
# test "godzilla aftermath" do
|
157
|
-
#
|
181
|
+
# assert_not_empty Foo.all
|
158
182
|
# end
|
159
183
|
# end
|
160
184
|
#
|
161
|
-
# If you preload your test database with all fixture data (probably
|
162
|
-
# transactional tests, then you may omit all fixtures declarations in your test cases since
|
185
|
+
# If you preload your test database with all fixture data (probably by running `rails db:fixtures:load`)
|
186
|
+
# and use transactional tests, then you may omit all fixtures declarations in your test cases since
|
163
187
|
# all the data's already there and every case rolls back its changes.
|
164
188
|
#
|
165
189
|
# In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to
|
@@ -415,180 +439,191 @@ module ActiveRecord
|
|
415
439
|
# possibly in a folder with the same name.
|
416
440
|
#++
|
417
441
|
|
418
|
-
MAX_ID = 2
|
419
|
-
|
420
|
-
@@all_cached_fixtures = Hash.new { |h,k| h[k] = {} }
|
442
|
+
MAX_ID = 2**30 - 1
|
421
443
|
|
422
|
-
|
423
|
-
config.pluralize_table_names ?
|
424
|
-
fixture_set_name.singularize.camelize :
|
425
|
-
fixture_set_name.camelize
|
426
|
-
end
|
427
|
-
|
428
|
-
def self.default_fixture_table_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc:
|
429
|
-
"#{ config.table_name_prefix }"\
|
430
|
-
"#{ fixture_set_name.tr('/', '_') }"\
|
431
|
-
"#{ config.table_name_suffix }".to_sym
|
432
|
-
end
|
444
|
+
@@all_cached_fixtures = Hash.new { |h, k| h[k] = {} }
|
433
445
|
|
434
|
-
|
435
|
-
@@all_cached_fixtures.clear
|
436
|
-
end
|
446
|
+
cattr_accessor :all_loaded_fixtures, default: {}
|
437
447
|
|
438
|
-
|
439
|
-
|
440
|
-
|
448
|
+
class ClassCache
|
449
|
+
def initialize(class_names, config)
|
450
|
+
@class_names = class_names.stringify_keys
|
451
|
+
@config = config
|
441
452
|
|
442
|
-
|
443
|
-
|
444
|
-
|
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
|
445
458
|
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
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
|
451
464
|
end
|
452
|
-
end
|
453
465
|
|
454
|
-
|
455
|
-
cache_for_connection(connection).update(fixtures_map)
|
456
|
-
end
|
466
|
+
private
|
457
467
|
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
nil
|
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
|
465
474
|
end
|
466
475
|
end
|
467
|
-
end
|
468
|
-
end
|
469
476
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
end
|
477
|
+
def default_fixture_model(fs_name, config)
|
478
|
+
ActiveRecord::FixtureSet.default_fixture_model_name(fs_name, config)
|
479
|
+
end
|
474
480
|
end
|
475
481
|
|
476
|
-
|
477
|
-
|
482
|
+
class << self
|
483
|
+
def default_fixture_model_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc:
|
484
|
+
config.pluralize_table_names ?
|
485
|
+
fixture_set_name.singularize.camelize :
|
486
|
+
fixture_set_name.camelize
|
487
|
+
end
|
478
488
|
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
489
|
+
def default_fixture_table_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc:
|
490
|
+
"#{ config.table_name_prefix }"\
|
491
|
+
"#{ fixture_set_name.tr('/', '_') }"\
|
492
|
+
"#{ config.table_name_suffix }".to_sym
|
493
|
+
end
|
483
494
|
|
484
|
-
|
485
|
-
|
495
|
+
def reset_cache
|
496
|
+
@@all_cached_fixtures.clear
|
486
497
|
end
|
487
498
|
|
488
|
-
def
|
489
|
-
|
490
|
-
klass = default_fixture_model(fs_name, @config).safe_constantize
|
491
|
-
insert_class(@class_names, fs_name, klass)
|
492
|
-
}
|
499
|
+
def cache_for_connection(connection)
|
500
|
+
@@all_cached_fixtures[connection]
|
493
501
|
end
|
494
502
|
|
495
|
-
|
503
|
+
def fixture_is_cached?(connection, table_name)
|
504
|
+
cache_for_connection(connection)[table_name]
|
505
|
+
end
|
496
506
|
|
497
|
-
def
|
498
|
-
|
499
|
-
|
500
|
-
class_names[name] = klass
|
507
|
+
def cached_fixtures(connection, keys_to_fetch = nil)
|
508
|
+
if keys_to_fetch
|
509
|
+
cache_for_connection(connection).values_at(*keys_to_fetch)
|
501
510
|
else
|
502
|
-
|
511
|
+
cache_for_connection(connection).values
|
503
512
|
end
|
504
513
|
end
|
505
514
|
|
506
|
-
def
|
507
|
-
|
515
|
+
def cache_fixtures(connection, fixtures_map)
|
516
|
+
cache_for_connection(connection).update(fixtures_map)
|
508
517
|
end
|
509
|
-
end
|
510
518
|
|
511
|
-
|
512
|
-
|
513
|
-
|
519
|
+
def instantiate_fixtures(object, fixture_set, load_instances = true)
|
520
|
+
return unless load_instances
|
521
|
+
fixture_set.each do |fixture_name, fixture|
|
522
|
+
object.instance_variable_set "@#{fixture_name}", fixture.find
|
523
|
+
rescue FixtureClassNotFound
|
524
|
+
nil
|
525
|
+
end
|
526
|
+
end
|
514
527
|
|
515
|
-
|
516
|
-
|
528
|
+
def instantiate_all_loaded_fixtures(object, load_instances = true)
|
529
|
+
all_loaded_fixtures.each_value do |fixture_set|
|
530
|
+
instantiate_fixtures(object, fixture_set, load_instances)
|
531
|
+
end
|
532
|
+
end
|
517
533
|
|
518
|
-
|
519
|
-
|
520
|
-
|
534
|
+
def create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base, &block)
|
535
|
+
fixture_set_names = Array(fixture_set_names).map(&:to_s)
|
536
|
+
class_names = ClassCache.new class_names, config
|
521
537
|
|
522
|
-
|
523
|
-
connection.
|
524
|
-
fixtures_map = {}
|
538
|
+
# FIXME: Apparently JK uses this.
|
539
|
+
connection = block_given? ? block : lambda { ActiveRecord::Base.connection }
|
525
540
|
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
541
|
+
fixture_files_to_read = fixture_set_names.reject do |fs_name|
|
542
|
+
fixture_is_cached?(connection.call, fs_name)
|
543
|
+
end
|
544
|
+
|
545
|
+
if fixture_files_to_read.any?
|
546
|
+
fixtures_map = read_and_insert(
|
547
|
+
fixtures_directory,
|
548
|
+
fixture_files_to_read,
|
549
|
+
class_names,
|
550
|
+
connection,
|
551
|
+
)
|
552
|
+
cache_fixtures(connection.call, fixtures_map)
|
553
|
+
end
|
554
|
+
cached_fixtures(connection.call, fixture_set_names)
|
555
|
+
end
|
556
|
+
|
557
|
+
# Returns a consistent, platform-independent identifier for +label+.
|
558
|
+
# Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes.
|
559
|
+
def identify(label, column_type = :integer)
|
560
|
+
if column_type == :uuid
|
561
|
+
Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, label.to_s)
|
562
|
+
else
|
563
|
+
Zlib.crc32(label.to_s) % MAX_ID
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
# Superclass for the evaluation contexts used by ERB fixtures.
|
568
|
+
def context_class
|
569
|
+
@context_class ||= Class.new
|
570
|
+
end
|
571
|
+
|
572
|
+
private
|
573
|
+
|
574
|
+
def read_and_insert(fixtures_directory, fixture_files, class_names, connection) # :nodoc:
|
575
|
+
fixtures_map = {}
|
576
|
+
fixture_sets = fixture_files.map do |fixture_set_name|
|
577
|
+
klass = class_names[fixture_set_name]
|
578
|
+
fixtures_map[fixture_set_name] = new( # ActiveRecord::FixtureSet.new
|
579
|
+
nil,
|
580
|
+
fixture_set_name,
|
532
581
|
klass,
|
533
|
-
::File.join(fixtures_directory,
|
582
|
+
::File.join(fixtures_directory, fixture_set_name)
|
583
|
+
)
|
534
584
|
end
|
585
|
+
update_all_loaded_fixtures(fixtures_map)
|
535
586
|
|
536
|
-
|
587
|
+
insert(fixture_sets, connection)
|
537
588
|
|
538
|
-
|
539
|
-
|
540
|
-
fixture_sets.each do |fs|
|
541
|
-
conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection
|
542
|
-
table_rows = fs.table_rows
|
589
|
+
fixtures_map
|
590
|
+
end
|
543
591
|
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
592
|
+
def insert(fixture_sets, connection) # :nodoc:
|
593
|
+
fixture_sets_by_connection = fixture_sets.group_by do |fixture_set|
|
594
|
+
if fixture_set.model_class
|
595
|
+
fixture_set.model_class.connection
|
596
|
+
else
|
597
|
+
connection.call
|
598
|
+
end
|
599
|
+
end
|
550
600
|
|
551
|
-
|
552
|
-
|
553
|
-
conn.insert_fixture(row, fixture_set_name)
|
554
|
-
end
|
555
|
-
end
|
601
|
+
fixture_sets_by_connection.each do |conn, set|
|
602
|
+
table_rows_for_connection = Hash.new { |h, k| h[k] = [] }
|
556
603
|
|
557
|
-
|
558
|
-
|
559
|
-
|
604
|
+
set.each do |fixture_set|
|
605
|
+
fixture_set.table_rows.each do |table, rows|
|
606
|
+
table_rows_for_connection[table].unshift(*rows)
|
560
607
|
end
|
561
608
|
end
|
562
|
-
end
|
563
609
|
|
564
|
-
|
565
|
-
end
|
566
|
-
end
|
567
|
-
cached_fixtures(connection, fixture_set_names)
|
568
|
-
end
|
610
|
+
conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys)
|
569
611
|
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
Zlib.crc32(label.to_s) % MAX_ID
|
577
|
-
end
|
578
|
-
end
|
579
|
-
|
580
|
-
# Superclass for the evaluation contexts used by ERB fixtures.
|
581
|
-
def self.context_class
|
582
|
-
@context_class ||= Class.new
|
583
|
-
end
|
612
|
+
# Cap primary key sequences to max(pk).
|
613
|
+
if conn.respond_to?(:reset_pk_sequence!)
|
614
|
+
set.each { |fs| conn.reset_pk_sequence!(fs.table_name) }
|
615
|
+
end
|
616
|
+
end
|
617
|
+
end
|
584
618
|
|
585
|
-
|
586
|
-
|
619
|
+
def update_all_loaded_fixtures(fixtures_map) # :nodoc:
|
620
|
+
all_loaded_fixtures.update(fixtures_map)
|
621
|
+
end
|
587
622
|
end
|
588
623
|
|
589
624
|
attr_reader :table_name, :name, :fixtures, :model_class, :config
|
590
625
|
|
591
|
-
def initialize(
|
626
|
+
def initialize(_, name, class_name, path, config = ActiveRecord::Base)
|
592
627
|
@name = name
|
593
628
|
@path = path
|
594
629
|
@config = config
|
@@ -597,18 +632,14 @@ module ActiveRecord
|
|
597
632
|
|
598
633
|
@fixtures = read_fixture_files(path)
|
599
634
|
|
600
|
-
@
|
601
|
-
|
602
|
-
@table_name = ( model_class.respond_to?(:table_name) ?
|
603
|
-
model_class.table_name :
|
604
|
-
self.class.default_fixture_table_name(name, config) )
|
635
|
+
@table_name = model_class&.table_name || self.class.default_fixture_table_name(name, config)
|
605
636
|
end
|
606
637
|
|
607
638
|
def [](x)
|
608
639
|
fixtures[x]
|
609
640
|
end
|
610
641
|
|
611
|
-
def []=(k,v)
|
642
|
+
def []=(k, v)
|
612
643
|
fixtures[k] = v
|
613
644
|
end
|
614
645
|
|
@@ -623,152 +654,18 @@ module ActiveRecord
|
|
623
654
|
# Returns a hash of rows to be inserted. The key is the table, the value is
|
624
655
|
# a list of rows to insert to that table.
|
625
656
|
def table_rows
|
626
|
-
now = config.default_timezone == :utc ? Time.now.utc : Time.now
|
627
|
-
|
628
657
|
# allow a standard key to be used for doing defaults in YAML
|
629
|
-
fixtures.delete(
|
630
|
-
|
631
|
-
# track any join tables we need to insert later
|
632
|
-
rows = Hash.new { |h,table| h[table] = [] }
|
633
|
-
|
634
|
-
rows[table_name] = fixtures.map do |label, fixture|
|
635
|
-
row = fixture.to_hash
|
636
|
-
|
637
|
-
if model_class
|
638
|
-
# fill in timestamp columns if they aren't specified and the model is set to record_timestamps
|
639
|
-
if model_class.record_timestamps
|
640
|
-
timestamp_column_names.each do |c_name|
|
641
|
-
row[c_name] = now unless row.key?(c_name)
|
642
|
-
end
|
643
|
-
end
|
644
|
-
|
645
|
-
# interpolate the fixture label
|
646
|
-
row.each do |key, value|
|
647
|
-
row[key] = value.gsub("$LABEL", label.to_s) if value.is_a?(String)
|
648
|
-
end
|
649
|
-
|
650
|
-
# generate a primary key if necessary
|
651
|
-
if has_primary_key_column? && !row.include?(primary_key_name)
|
652
|
-
row[primary_key_name] = ActiveRecord::FixtureSet.identify(label, primary_key_type)
|
653
|
-
end
|
654
|
-
|
655
|
-
# Resolve enums
|
656
|
-
model_class.defined_enums.each do |name, values|
|
657
|
-
if row.include?(name)
|
658
|
-
row[name] = values.fetch(row[name], row[name])
|
659
|
-
end
|
660
|
-
end
|
661
|
-
|
662
|
-
# If STI is used, find the correct subclass for association reflection
|
663
|
-
reflection_class =
|
664
|
-
if row.include?(inheritance_column_name)
|
665
|
-
row[inheritance_column_name].constantize rescue model_class
|
666
|
-
else
|
667
|
-
model_class
|
668
|
-
end
|
669
|
-
|
670
|
-
reflection_class._reflections.each_value do |association|
|
671
|
-
case association.macro
|
672
|
-
when :belongs_to
|
673
|
-
# Do not replace association name with association foreign key if they are named the same
|
674
|
-
fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s
|
675
|
-
|
676
|
-
if association.name.to_s != fk_name && value = row.delete(association.name.to_s)
|
677
|
-
if association.polymorphic? && value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
|
678
|
-
# support polymorphic belongs_to as "label (Type)"
|
679
|
-
row[association.foreign_type] = $1
|
680
|
-
end
|
681
|
-
|
682
|
-
fk_type = reflection_class.type_for_attribute(fk_name).type
|
683
|
-
row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
|
684
|
-
end
|
685
|
-
when :has_many
|
686
|
-
if association.options[:through]
|
687
|
-
add_join_records(rows, row, HasManyThroughProxy.new(association))
|
688
|
-
end
|
689
|
-
end
|
690
|
-
end
|
691
|
-
end
|
692
|
-
|
693
|
-
row
|
694
|
-
end
|
695
|
-
rows
|
696
|
-
end
|
697
|
-
|
698
|
-
class ReflectionProxy # :nodoc:
|
699
|
-
def initialize(association)
|
700
|
-
@association = association
|
701
|
-
end
|
702
|
-
|
703
|
-
def join_table
|
704
|
-
@association.join_table
|
705
|
-
end
|
706
|
-
|
707
|
-
def name
|
708
|
-
@association.name
|
709
|
-
end
|
710
|
-
|
711
|
-
def primary_key_type
|
712
|
-
@association.klass.type_for_attribute(@association.klass.primary_key).type
|
713
|
-
end
|
714
|
-
end
|
658
|
+
fixtures.delete("DEFAULTS")
|
715
659
|
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
@association.through_reflection.foreign_key
|
723
|
-
end
|
724
|
-
|
725
|
-
def join_table
|
726
|
-
@association.through_reflection.table_name
|
727
|
-
end
|
660
|
+
TableRows.new(
|
661
|
+
table_name,
|
662
|
+
model_class: model_class,
|
663
|
+
fixtures: fixtures,
|
664
|
+
config: config,
|
665
|
+
).to_hash
|
728
666
|
end
|
729
667
|
|
730
668
|
private
|
731
|
-
def primary_key_name
|
732
|
-
@primary_key_name ||= model_class && model_class.primary_key
|
733
|
-
end
|
734
|
-
|
735
|
-
def primary_key_type
|
736
|
-
@primary_key_type ||= model_class && model_class.type_for_attribute(model_class.primary_key).type
|
737
|
-
end
|
738
|
-
|
739
|
-
def add_join_records(rows, row, association)
|
740
|
-
# This is the case when the join table has no fixtures file
|
741
|
-
if (targets = row.delete(association.name.to_s))
|
742
|
-
table_name = association.join_table
|
743
|
-
column_type = association.primary_key_type
|
744
|
-
lhs_key = association.lhs_key
|
745
|
-
rhs_key = association.rhs_key
|
746
|
-
|
747
|
-
targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
|
748
|
-
rows[table_name].concat targets.map { |target|
|
749
|
-
{ lhs_key => row[primary_key_name],
|
750
|
-
rhs_key => ActiveRecord::FixtureSet.identify(target, column_type) }
|
751
|
-
}
|
752
|
-
end
|
753
|
-
end
|
754
|
-
|
755
|
-
def has_primary_key_column?
|
756
|
-
@has_primary_key_column ||= primary_key_name &&
|
757
|
-
model_class.columns.any? { |c| c.name == primary_key_name }
|
758
|
-
end
|
759
|
-
|
760
|
-
def timestamp_column_names
|
761
|
-
@timestamp_column_names ||=
|
762
|
-
%w(created_at created_on updated_at updated_on) & column_names
|
763
|
-
end
|
764
|
-
|
765
|
-
def inheritance_column_name
|
766
|
-
@inheritance_column_name ||= model_class && model_class.inheritance_column
|
767
|
-
end
|
768
|
-
|
769
|
-
def column_names
|
770
|
-
@column_names ||= @connection.columns(@table_name).collect(&:name)
|
771
|
-
end
|
772
669
|
|
773
670
|
def model_class=(class_name)
|
774
671
|
if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
|
@@ -799,7 +696,6 @@ module ActiveRecord
|
|
799
696
|
def yaml_file_path(path)
|
800
697
|
"#{path}.yml"
|
801
698
|
end
|
802
|
-
|
803
699
|
end
|
804
700
|
|
805
701
|
class Fixture #:nodoc:
|
@@ -833,212 +729,9 @@ module ActiveRecord
|
|
833
729
|
alias :to_hash :fixture
|
834
730
|
|
835
731
|
def find
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
end
|
840
|
-
else
|
841
|
-
raise FixtureClassNotFound, "No class attached to find."
|
842
|
-
end
|
843
|
-
end
|
844
|
-
end
|
845
|
-
end
|
846
|
-
|
847
|
-
module ActiveRecord
|
848
|
-
module TestFixtures
|
849
|
-
extend ActiveSupport::Concern
|
850
|
-
|
851
|
-
def before_setup # :nodoc:
|
852
|
-
setup_fixtures
|
853
|
-
super
|
854
|
-
end
|
855
|
-
|
856
|
-
def after_teardown # :nodoc:
|
857
|
-
super
|
858
|
-
teardown_fixtures
|
859
|
-
end
|
860
|
-
|
861
|
-
included do
|
862
|
-
class_attribute :fixture_path, :instance_writer => false
|
863
|
-
class_attribute :fixture_table_names
|
864
|
-
class_attribute :fixture_class_names
|
865
|
-
class_attribute :use_transactional_tests
|
866
|
-
class_attribute :use_transactional_fixtures
|
867
|
-
class_attribute :use_instantiated_fixtures # true, false, or :no_instances
|
868
|
-
class_attribute :pre_loaded_fixtures
|
869
|
-
class_attribute :config
|
870
|
-
|
871
|
-
singleton_class.deprecate 'use_transactional_fixtures=' => 'use use_transactional_tests= instead'
|
872
|
-
|
873
|
-
self.fixture_table_names = []
|
874
|
-
self.use_instantiated_fixtures = false
|
875
|
-
self.pre_loaded_fixtures = false
|
876
|
-
self.config = ActiveRecord::Base
|
877
|
-
|
878
|
-
self.fixture_class_names = {}
|
879
|
-
|
880
|
-
silence_warnings do
|
881
|
-
define_singleton_method :use_transactional_tests do
|
882
|
-
if use_transactional_fixtures.nil?
|
883
|
-
true
|
884
|
-
else
|
885
|
-
use_transactional_fixtures
|
886
|
-
end
|
887
|
-
end
|
888
|
-
end
|
889
|
-
end
|
890
|
-
|
891
|
-
module ClassMethods
|
892
|
-
# Sets the model class for a fixture when the class name cannot be inferred from the fixture name.
|
893
|
-
#
|
894
|
-
# Examples:
|
895
|
-
#
|
896
|
-
# set_fixture_class some_fixture: SomeModel,
|
897
|
-
# 'namespaced/fixture' => Another::Model
|
898
|
-
#
|
899
|
-
# The keys must be the fixture names, that coincide with the short paths to the fixture files.
|
900
|
-
def set_fixture_class(class_names = {})
|
901
|
-
self.fixture_class_names = self.fixture_class_names.merge(class_names.stringify_keys)
|
902
|
-
end
|
903
|
-
|
904
|
-
def fixtures(*fixture_set_names)
|
905
|
-
if fixture_set_names.first == :all
|
906
|
-
fixture_set_names = Dir["#{fixture_path}/{**,*}/*.{yml}"]
|
907
|
-
fixture_set_names.map! { |f| f[(fixture_path.to_s.size + 1)..-5] }
|
908
|
-
else
|
909
|
-
fixture_set_names = fixture_set_names.flatten.map(&:to_s)
|
910
|
-
end
|
911
|
-
|
912
|
-
self.fixture_table_names |= fixture_set_names
|
913
|
-
setup_fixture_accessors(fixture_set_names)
|
914
|
-
end
|
915
|
-
|
916
|
-
def setup_fixture_accessors(fixture_set_names = nil)
|
917
|
-
fixture_set_names = Array(fixture_set_names || fixture_table_names)
|
918
|
-
methods = Module.new do
|
919
|
-
fixture_set_names.each do |fs_name|
|
920
|
-
fs_name = fs_name.to_s
|
921
|
-
accessor_name = fs_name.tr('/', '_').to_sym
|
922
|
-
|
923
|
-
define_method(accessor_name) do |*fixture_names|
|
924
|
-
force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
|
925
|
-
|
926
|
-
@fixture_cache[fs_name] ||= {}
|
927
|
-
|
928
|
-
instances = fixture_names.map do |f_name|
|
929
|
-
f_name = f_name.to_s if f_name.is_a?(Symbol)
|
930
|
-
@fixture_cache[fs_name].delete(f_name) if force_reload
|
931
|
-
|
932
|
-
if @loaded_fixtures[fs_name][f_name]
|
933
|
-
@fixture_cache[fs_name][f_name] ||= @loaded_fixtures[fs_name][f_name].find
|
934
|
-
else
|
935
|
-
raise StandardError, "No fixture named '#{f_name}' found for fixture set '#{fs_name}'"
|
936
|
-
end
|
937
|
-
end
|
938
|
-
|
939
|
-
instances.size == 1 ? instances.first : instances
|
940
|
-
end
|
941
|
-
private accessor_name
|
942
|
-
end
|
943
|
-
end
|
944
|
-
include methods
|
945
|
-
end
|
946
|
-
|
947
|
-
def uses_transaction(*methods)
|
948
|
-
@uses_transaction = [] unless defined?(@uses_transaction)
|
949
|
-
@uses_transaction.concat methods.map(&:to_s)
|
950
|
-
end
|
951
|
-
|
952
|
-
def uses_transaction?(method)
|
953
|
-
@uses_transaction = [] unless defined?(@uses_transaction)
|
954
|
-
@uses_transaction.include?(method.to_s)
|
955
|
-
end
|
956
|
-
end
|
957
|
-
|
958
|
-
def run_in_transaction?
|
959
|
-
use_transactional_tests &&
|
960
|
-
!self.class.uses_transaction?(method_name)
|
961
|
-
end
|
962
|
-
|
963
|
-
def setup_fixtures(config = ActiveRecord::Base)
|
964
|
-
if pre_loaded_fixtures && !use_transactional_tests
|
965
|
-
raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_tests'
|
966
|
-
end
|
967
|
-
|
968
|
-
@fixture_cache = {}
|
969
|
-
@fixture_connections = []
|
970
|
-
@@already_loaded_fixtures ||= {}
|
971
|
-
|
972
|
-
# Load fixtures once and begin transaction.
|
973
|
-
if run_in_transaction?
|
974
|
-
if @@already_loaded_fixtures[self.class]
|
975
|
-
@loaded_fixtures = @@already_loaded_fixtures[self.class]
|
976
|
-
else
|
977
|
-
@loaded_fixtures = load_fixtures(config)
|
978
|
-
@@already_loaded_fixtures[self.class] = @loaded_fixtures
|
979
|
-
end
|
980
|
-
@fixture_connections = enlist_fixture_connections
|
981
|
-
@fixture_connections.each do |connection|
|
982
|
-
connection.begin_transaction joinable: false
|
983
|
-
end
|
984
|
-
# Load fixtures for every test.
|
985
|
-
else
|
986
|
-
ActiveRecord::FixtureSet.reset_cache
|
987
|
-
@@already_loaded_fixtures[self.class] = nil
|
988
|
-
@loaded_fixtures = load_fixtures(config)
|
989
|
-
end
|
990
|
-
|
991
|
-
# Instantiate fixtures for every test if requested.
|
992
|
-
instantiate_fixtures if use_instantiated_fixtures
|
993
|
-
end
|
994
|
-
|
995
|
-
def teardown_fixtures
|
996
|
-
# Rollback changes if a transaction is active.
|
997
|
-
if run_in_transaction?
|
998
|
-
@fixture_connections.each do |connection|
|
999
|
-
connection.rollback_transaction if connection.transaction_open?
|
1000
|
-
end
|
1001
|
-
@fixture_connections.clear
|
1002
|
-
else
|
1003
|
-
ActiveRecord::FixtureSet.reset_cache
|
1004
|
-
end
|
1005
|
-
|
1006
|
-
ActiveRecord::Base.clear_active_connections!
|
1007
|
-
end
|
1008
|
-
|
1009
|
-
def enlist_fixture_connections
|
1010
|
-
ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
|
1011
|
-
end
|
1012
|
-
|
1013
|
-
private
|
1014
|
-
def load_fixtures(config)
|
1015
|
-
fixtures = ActiveRecord::FixtureSet.create_fixtures(fixture_path, fixture_table_names, fixture_class_names, config)
|
1016
|
-
Hash[fixtures.map { |f| [f.name, f] }]
|
1017
|
-
end
|
1018
|
-
|
1019
|
-
def instantiate_fixtures
|
1020
|
-
if pre_loaded_fixtures
|
1021
|
-
raise RuntimeError, 'Load fixtures before instantiating them.' if ActiveRecord::FixtureSet.all_loaded_fixtures.empty?
|
1022
|
-
ActiveRecord::FixtureSet.instantiate_all_loaded_fixtures(self, load_instances?)
|
1023
|
-
else
|
1024
|
-
raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
|
1025
|
-
@loaded_fixtures.each_value do |fixture_set|
|
1026
|
-
ActiveRecord::FixtureSet.instantiate_fixtures(self, fixture_set, load_instances?)
|
1027
|
-
end
|
1028
|
-
end
|
1029
|
-
end
|
1030
|
-
|
1031
|
-
def load_instances?
|
1032
|
-
use_instantiated_fixtures != :no_instances
|
1033
|
-
end
|
1034
|
-
end
|
1035
|
-
end
|
1036
|
-
|
1037
|
-
class ActiveRecord::FixtureSet::RenderContext # :nodoc:
|
1038
|
-
def self.create_subclass
|
1039
|
-
Class.new ActiveRecord::FixtureSet.context_class do
|
1040
|
-
def get_binding
|
1041
|
-
binding()
|
732
|
+
raise FixtureClassNotFound, "No class attached to find." unless model_class
|
733
|
+
model_class.unscoped do
|
734
|
+
model_class.find(fixture[model_class.primary_key])
|
1042
735
|
end
|
1043
736
|
end
|
1044
737
|
end
|