activerecord 5.0.7.2 → 6.1.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 +4 -4
- data/CHANGELOG.md +829 -2015
- data/MIT-LICENSE +3 -1
- data/README.rdoc +11 -9
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record.rb +37 -29
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +30 -18
- data/lib/active_record/associations.rb +1714 -1596
- data/lib/active_record/associations/alias_tracker.rb +36 -42
- data/lib/active_record/associations/association.rb +143 -68
- data/lib/active_record/associations/association_scope.rb +98 -94
- data/lib/active_record/associations/belongs_to_association.rb +76 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
- data/lib/active_record/associations/builder/association.rb +27 -28
- data/lib/active_record/associations/builder/belongs_to.rb +52 -60
- data/lib/active_record/associations/builder/collection_association.rb +12 -22
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
- data/lib/active_record/associations/builder/has_many.rb +10 -2
- data/lib/active_record/associations/builder/has_one.rb +35 -2
- data/lib/active_record/associations/builder/singular_association.rb +5 -1
- data/lib/active_record/associations/collection_association.rb +104 -259
- data/lib/active_record/associations/collection_proxy.rb +169 -125
- data/lib/active_record/associations/foreign_association.rb +22 -0
- data/lib/active_record/associations/has_many_association.rb +46 -31
- data/lib/active_record/associations/has_many_through_association.rb +66 -46
- data/lib/active_record/associations/has_one_association.rb +71 -52
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +169 -180
- data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/preloader.rb +97 -104
- data/lib/active_record/associations/preloader/association.rb +109 -97
- data/lib/active_record/associations/preloader/through_association.rb +77 -76
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +27 -15
- data/lib/active_record/attribute_assignment.rb +55 -60
- data/lib/active_record/attribute_methods.rb +111 -141
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
- data/lib/active_record/attribute_methods/dirty.rb +172 -112
- data/lib/active_record/attribute_methods/primary_key.rb +88 -91
- data/lib/active_record/attribute_methods/query.rb +6 -8
- data/lib/active_record/attribute_methods/read.rb +18 -50
- data/lib/active_record/attribute_methods/serialization.rb +38 -10
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
- data/lib/active_record/attribute_methods/write.rb +25 -32
- data/lib/active_record/attributes.rb +69 -31
- data/lib/active_record/autosave_association.rb +102 -66
- data/lib/active_record/base.rb +16 -25
- data/lib/active_record/callbacks.rb +202 -43
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -12
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
- data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
- data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
- data/lib/active_record/connection_adapters/column.rb +55 -13
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
- 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 +6 -6
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -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 +30 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -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 +18 -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/quoting.rb +98 -38
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
- data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
- 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 +170 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +287 -45
- data/lib/active_record/core.rb +385 -181
- data/lib/active_record/counter_cache.rb +60 -28
- data/lib/active_record/database_configurations.rb +272 -0
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +87 -87
- data/lib/active_record/enum.rb +122 -47
- data/lib/active_record/errors.rb +153 -22
- data/lib/active_record/explain.rb +13 -8
- 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 +20 -22
- data/lib/active_record/fixture_set/model_metadata.rb +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +246 -507
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +168 -95
- data/lib/active_record/insert_all.rb +208 -0
- data/lib/active_record/integration.rb +114 -25
- data/lib/active_record/internal_metadata.rb +30 -24
- data/lib/active_record/legacy_yaml_adapter.rb +11 -5
- data/lib/active_record/locking/optimistic.rb +81 -85
- data/lib/active_record/locking/pessimistic.rb +22 -6
- data/lib/active_record/log_subscriber.rb +68 -31
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/migration.rb +439 -342
- data/lib/active_record/migration/command_recorder.rb +152 -98
- data/lib/active_record/migration/compatibility.rb +229 -60
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/model_schema.rb +230 -122
- data/lib/active_record/nested_attributes.rb +213 -203
- data/lib/active_record/no_touching.rb +11 -2
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +471 -97
- data/lib/active_record/query_cache.rb +23 -12
- data/lib/active_record/querying.rb +43 -25
- data/lib/active_record/railtie.rb +155 -43
- 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 +507 -195
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +245 -269
- data/lib/active_record/relation.rb +475 -324
- data/lib/active_record/relation/batches.rb +125 -72
- data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
- data/lib/active_record/relation/calculations.rb +267 -171
- data/lib/active_record/relation/delegation.rb +73 -69
- data/lib/active_record/relation/finder_methods.rb +238 -248
- data/lib/active_record/relation/from_clause.rb +7 -9
- data/lib/active_record/relation/merger.rb +95 -77
- data/lib/active_record/relation/predicate_builder.rb +109 -110
- data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +654 -374
- data/lib/active_record/relation/record_fetch_warning.rb +8 -6
- data/lib/active_record/relation/spawn_methods.rb +15 -14
- data/lib/active_record/relation/where_clause.rb +171 -109
- data/lib/active_record/result.rb +88 -51
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +73 -100
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +101 -69
- data/lib/active_record/schema_migration.rb +16 -12
- data/lib/active_record/scoping.rb +20 -20
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +39 -30
- data/lib/active_record/secure_token.rb +19 -9
- data/lib/active_record/serialization.rb +7 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +80 -29
- data/lib/active_record/store.rb +122 -42
- data/lib/active_record/suppressor.rb +6 -3
- data/lib/active_record/table_metadata.rb +51 -39
- data/lib/active_record/tasks/database_tasks.rb +332 -115
- data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
- data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +246 -0
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +26 -24
- data/lib/active_record/transactions.rb +121 -184
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +29 -17
- data/lib/active_record/type/adapter_specific_registry.rb +44 -48
- 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 -4
- 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 +20 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +12 -1
- data/lib/active_record/type/type_map.rb +14 -17
- data/lib/active_record/type/unsigned_integer.rb +16 -0
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/type_caster/connection.rb +17 -13
- data/lib/active_record/type_caster/map.rb +10 -6
- data/lib/active_record/validations.rb +8 -5
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +4 -3
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +52 -45
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +54 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +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.rb +70 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +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/order_predications.rb +13 -0
- data/lib/arel/predications.rb +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record.rb +7 -5
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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.rb +22 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
- data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
- 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 → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +141 -57
- 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.rb +0 -213
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute_decorators.rb +0 -67
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/attribute_set/builder.rb +0 -132
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
- 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/base_handler.rb +0 -17
- 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/relation/where_clause_factory.rb +0 -38
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# NOTE: This class has to be defined in compact style in
|
4
|
+
# order for rendering context subclassing to work correctly.
|
5
|
+
class ActiveRecord::FixtureSet::RenderContext # :nodoc:
|
6
|
+
def self.create_subclass
|
7
|
+
Class.new(ActiveRecord::FixtureSet.context_class) do
|
8
|
+
def get_binding
|
9
|
+
binding()
|
10
|
+
end
|
11
|
+
|
12
|
+
def binary(path)
|
13
|
+
%(!!binary "#{Base64.strict_encode64(File.binread(path))}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class FixtureSet
|
5
|
+
class TableRow # :nodoc:
|
6
|
+
class ReflectionProxy # :nodoc:
|
7
|
+
def initialize(association)
|
8
|
+
@association = association
|
9
|
+
end
|
10
|
+
|
11
|
+
def join_table
|
12
|
+
@association.join_table
|
13
|
+
end
|
14
|
+
|
15
|
+
def name
|
16
|
+
@association.name
|
17
|
+
end
|
18
|
+
|
19
|
+
def primary_key_type
|
20
|
+
@association.klass.type_for_attribute(@association.klass.primary_key).type
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class HasManyThroughProxy < ReflectionProxy # :nodoc:
|
25
|
+
def rhs_key
|
26
|
+
@association.foreign_key
|
27
|
+
end
|
28
|
+
|
29
|
+
def lhs_key
|
30
|
+
@association.through_reflection.foreign_key
|
31
|
+
end
|
32
|
+
|
33
|
+
def join_table
|
34
|
+
@association.through_reflection.table_name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(fixture, table_rows:, label:, now:)
|
39
|
+
@table_rows = table_rows
|
40
|
+
@label = label
|
41
|
+
@now = now
|
42
|
+
@row = fixture.to_hash
|
43
|
+
fill_row_model_attributes
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_hash
|
47
|
+
@row
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def model_metadata
|
52
|
+
@table_rows.model_metadata
|
53
|
+
end
|
54
|
+
|
55
|
+
def model_class
|
56
|
+
@table_rows.model_class
|
57
|
+
end
|
58
|
+
|
59
|
+
def fill_row_model_attributes
|
60
|
+
return unless model_class
|
61
|
+
fill_timestamps
|
62
|
+
interpolate_label
|
63
|
+
generate_primary_key
|
64
|
+
resolve_enums
|
65
|
+
resolve_sti_reflections
|
66
|
+
end
|
67
|
+
|
68
|
+
def reflection_class
|
69
|
+
@reflection_class ||= if @row.include?(model_metadata.inheritance_column_name)
|
70
|
+
@row[model_metadata.inheritance_column_name].constantize rescue model_class
|
71
|
+
else
|
72
|
+
model_class
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def fill_timestamps
|
77
|
+
# fill in timestamp columns if they aren't specified and the model is set to record_timestamps
|
78
|
+
if model_class.record_timestamps
|
79
|
+
model_metadata.timestamp_column_names.each do |c_name|
|
80
|
+
@row[c_name] = @now unless @row.key?(c_name)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def interpolate_label
|
86
|
+
# interpolate the fixture label
|
87
|
+
@row.each do |key, value|
|
88
|
+
@row[key] = value.gsub("$LABEL", @label.to_s) if value.is_a?(String)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def generate_primary_key
|
93
|
+
# generate a primary key if necessary
|
94
|
+
if model_metadata.has_primary_key_column? && !@row.include?(model_metadata.primary_key_name)
|
95
|
+
@row[model_metadata.primary_key_name] = ActiveRecord::FixtureSet.identify(
|
96
|
+
@label, model_metadata.primary_key_type
|
97
|
+
)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def resolve_enums
|
102
|
+
model_class.defined_enums.each do |name, values|
|
103
|
+
if @row.include?(name)
|
104
|
+
@row[name] = values.fetch(@row[name], @row[name])
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def resolve_sti_reflections
|
110
|
+
# If STI is used, find the correct subclass for association reflection
|
111
|
+
reflection_class._reflections.each_value do |association|
|
112
|
+
case association.macro
|
113
|
+
when :belongs_to
|
114
|
+
# Do not replace association name with association foreign key if they are named the same
|
115
|
+
fk_name = association.join_foreign_key
|
116
|
+
|
117
|
+
if association.name.to_s != fk_name && value = @row.delete(association.name.to_s)
|
118
|
+
if association.polymorphic? && value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
|
119
|
+
# support polymorphic belongs_to as "label (Type)"
|
120
|
+
@row[association.join_foreign_type] = $1
|
121
|
+
end
|
122
|
+
|
123
|
+
fk_type = reflection_class.type_for_attribute(fk_name).type
|
124
|
+
@row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
|
125
|
+
end
|
126
|
+
when :has_many
|
127
|
+
if association.options[:through]
|
128
|
+
add_join_records(HasManyThroughProxy.new(association))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_join_records(association)
|
135
|
+
# This is the case when the join table has no fixtures file
|
136
|
+
if (targets = @row.delete(association.name.to_s))
|
137
|
+
table_name = association.join_table
|
138
|
+
column_type = association.primary_key_type
|
139
|
+
lhs_key = association.lhs_key
|
140
|
+
rhs_key = association.rhs_key
|
141
|
+
|
142
|
+
targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
|
143
|
+
joins = targets.map do |target|
|
144
|
+
{ lhs_key => @row[model_metadata.primary_key_name],
|
145
|
+
rhs_key => ActiveRecord::FixtureSet.identify(target, column_type) }
|
146
|
+
end
|
147
|
+
@table_rows.tables[table_name].concat(joins)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/fixture_set/table_row"
|
4
|
+
require "active_record/fixture_set/model_metadata"
|
5
|
+
|
6
|
+
module ActiveRecord
|
7
|
+
class FixtureSet
|
8
|
+
class TableRows # :nodoc:
|
9
|
+
def initialize(table_name, model_class:, fixtures:, config:)
|
10
|
+
@model_class = model_class
|
11
|
+
|
12
|
+
# track any join tables we need to insert later
|
13
|
+
@tables = Hash.new { |h, table| h[table] = [] }
|
14
|
+
|
15
|
+
# ensure this table is loaded before any HABTM associations
|
16
|
+
@tables[table_name] = nil
|
17
|
+
|
18
|
+
build_table_rows_from(table_name, fixtures, config)
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :tables, :model_class
|
22
|
+
|
23
|
+
def to_hash
|
24
|
+
@tables.transform_values { |rows| rows.map(&:to_hash) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def model_metadata
|
28
|
+
@model_metadata ||= ModelMetadata.new(model_class)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def build_table_rows_from(table_name, fixtures, config)
|
33
|
+
now = config.default_timezone == :utc ? Time.now.utc : Time.now
|
34
|
+
|
35
|
+
@tables[table_name] = fixtures.map do |label, fixture|
|
36
|
+
TableRow.new(
|
37
|
+
fixture,
|
38
|
+
table_rows: self,
|
39
|
+
label: label,
|
40
|
+
now: now,
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,11 +1,15 @@
|
|
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"
|
9
13
|
|
10
14
|
module ActiveRecord
|
11
15
|
class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc:
|
@@ -36,7 +40,7 @@ module ActiveRecord
|
|
36
40
|
# separated by a blank line for your viewing pleasure.
|
37
41
|
#
|
38
42
|
# Note: Fixtures are unordered. If you want ordered fixtures, use the omap YAML type.
|
39
|
-
# See
|
43
|
+
# See https://yaml.org/type/omap.html
|
40
44
|
# for the specification. You will need ordered fixtures when you have foreign key constraints
|
41
45
|
# on keys in the same table. This is commonly needed for tree structures. Example:
|
42
46
|
#
|
@@ -55,7 +59,7 @@ module ActiveRecord
|
|
55
59
|
# Since fixtures are a testing construct, we use them in our unit and functional tests. There
|
56
60
|
# are two ways to use the fixtures, but first let's take a look at a sample unit test:
|
57
61
|
#
|
58
|
-
# require
|
62
|
+
# require "test_helper"
|
59
63
|
#
|
60
64
|
# class WebSiteTest < ActiveSupport::TestCase
|
61
65
|
# test "web_site_count" do
|
@@ -66,17 +70,36 @@ module ActiveRecord
|
|
66
70
|
# By default, +test_helper.rb+ will load all of your fixtures into your test
|
67
71
|
# database, so this test will succeed.
|
68
72
|
#
|
69
|
-
# The testing environment will automatically load the
|
73
|
+
# The testing environment will automatically load all the fixtures into the database before each
|
70
74
|
# test. To ensure consistent data, the environment deletes the fixtures before running the load.
|
71
75
|
#
|
72
76
|
# 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:
|
77
|
+
# using a special dynamic method, which has the same name as the model.
|
75
78
|
#
|
76
|
-
#
|
79
|
+
# Passing in a fixture name to this dynamic method returns the fixture matching this name:
|
80
|
+
#
|
81
|
+
# test "find one" do
|
77
82
|
# assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
|
78
83
|
# end
|
79
84
|
#
|
85
|
+
# Passing in multiple fixture names returns all fixtures matching these names:
|
86
|
+
#
|
87
|
+
# test "find all by name" do
|
88
|
+
# assert_equal 2, web_sites(:rubyonrails, :google).length
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# Passing in no arguments returns all fixtures:
|
92
|
+
#
|
93
|
+
# test "find all" do
|
94
|
+
# assert_equal 2, web_sites.length
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# Passing in any fixture name that does not exist will raise <tt>StandardError</tt>:
|
98
|
+
#
|
99
|
+
# test "find by name that does not exist" do
|
100
|
+
# assert_raise(StandardError) { web_sites(:reddit) }
|
101
|
+
# end
|
102
|
+
#
|
80
103
|
# Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the
|
81
104
|
# following tests:
|
82
105
|
#
|
@@ -88,7 +111,7 @@ module ActiveRecord
|
|
88
111
|
# assert_equal "Ruby on Rails", @rubyonrails.name
|
89
112
|
# end
|
90
113
|
#
|
91
|
-
# In order to use these methods to access fixtured data within your
|
114
|
+
# In order to use these methods to access fixtured data within your test cases, you must specify one of the
|
92
115
|
# following in your ActiveSupport::TestCase-derived class:
|
93
116
|
#
|
94
117
|
# - to fully enable instantiated fixtures (enable alternate methods #1 and #2 above)
|
@@ -103,7 +126,7 @@ module ActiveRecord
|
|
103
126
|
#
|
104
127
|
# = Dynamic fixtures with ERB
|
105
128
|
#
|
106
|
-
#
|
129
|
+
# Sometimes you don't care about the content of the fixtures as much as you care about the volume.
|
107
130
|
# In these cases, you can mix ERB in with your YAML fixtures to create a bunch of fixtures for load
|
108
131
|
# testing, like:
|
109
132
|
#
|
@@ -126,7 +149,7 @@ module ActiveRecord
|
|
126
149
|
# unwanted inter-test dependencies. Methods used by multiple fixtures should be defined in a module
|
127
150
|
# that is included in ActiveRecord::FixtureSet.context_class.
|
128
151
|
#
|
129
|
-
# - define a helper method in
|
152
|
+
# - define a helper method in <tt>test_helper.rb</tt>
|
130
153
|
# module FixtureFileHelpers
|
131
154
|
# def file_sha(path)
|
132
155
|
# Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
|
@@ -148,18 +171,18 @@ module ActiveRecord
|
|
148
171
|
# self.use_transactional_tests = true
|
149
172
|
#
|
150
173
|
# test "godzilla" do
|
151
|
-
#
|
174
|
+
# assert_not_empty Foo.all
|
152
175
|
# Foo.destroy_all
|
153
|
-
#
|
176
|
+
# assert_empty Foo.all
|
154
177
|
# end
|
155
178
|
#
|
156
179
|
# test "godzilla aftermath" do
|
157
|
-
#
|
180
|
+
# assert_not_empty Foo.all
|
158
181
|
# end
|
159
182
|
# end
|
160
183
|
#
|
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
|
184
|
+
# If you preload your test database with all fixture data (probably by running `bin/rails db:fixtures:load`)
|
185
|
+
# and use transactional tests, then you may omit all fixtures declarations in your test cases since
|
163
186
|
# all the data's already there and every case rolls back its changes.
|
164
187
|
#
|
165
188
|
# In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to
|
@@ -396,12 +419,35 @@ module ActiveRecord
|
|
396
419
|
#
|
397
420
|
# Any fixture labeled "DEFAULTS" is safely ignored.
|
398
421
|
#
|
422
|
+
# Besides using "DEFAULTS", you can also specify what fixtures will
|
423
|
+
# be ignored by setting "ignore" in "_fixture" section.
|
424
|
+
#
|
425
|
+
# # users.yml
|
426
|
+
# _fixture:
|
427
|
+
# ignore:
|
428
|
+
# - base
|
429
|
+
# # or use "ignore: base" when there is only one fixture needs to be ignored.
|
430
|
+
#
|
431
|
+
# base: &base
|
432
|
+
# admin: false
|
433
|
+
# introduction: "This is a default description"
|
434
|
+
#
|
435
|
+
# admin:
|
436
|
+
# <<: *base
|
437
|
+
# admin: true
|
438
|
+
#
|
439
|
+
# visitor:
|
440
|
+
# <<: *base
|
441
|
+
#
|
442
|
+
# In the above example, 'base' will be ignored when creating fixtures.
|
443
|
+
# This can be used for common attributes inheriting.
|
444
|
+
#
|
399
445
|
# == Configure the fixture model class
|
400
446
|
#
|
401
447
|
# It's possible to set the fixture's model class directly in the YAML file.
|
402
448
|
# This is helpful when fixtures are loaded outside tests and
|
403
449
|
# +set_fixture_class+ is not available (e.g.
|
404
|
-
# when running <tt>rails db:fixtures:load</tt>).
|
450
|
+
# when running <tt>bin/rails db:fixtures:load</tt>).
|
405
451
|
#
|
406
452
|
# _fixture:
|
407
453
|
# model_class: User
|
@@ -415,180 +461,197 @@ module ActiveRecord
|
|
415
461
|
# possibly in a folder with the same name.
|
416
462
|
#++
|
417
463
|
|
418
|
-
MAX_ID = 2
|
464
|
+
MAX_ID = 2**30 - 1
|
419
465
|
|
420
|
-
@@all_cached_fixtures = Hash.new { |h,k| h[k] = {} }
|
466
|
+
@@all_cached_fixtures = Hash.new { |h, k| h[k] = {} }
|
421
467
|
|
422
|
-
|
423
|
-
config.pluralize_table_names ?
|
424
|
-
fixture_set_name.singularize.camelize :
|
425
|
-
fixture_set_name.camelize
|
426
|
-
end
|
468
|
+
cattr_accessor :all_loaded_fixtures, default: {}
|
427
469
|
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
end
|
470
|
+
class ClassCache
|
471
|
+
def initialize(class_names, config)
|
472
|
+
@class_names = class_names.stringify_keys
|
473
|
+
@config = config
|
433
474
|
|
434
|
-
|
435
|
-
|
436
|
-
|
475
|
+
# Remove string values that aren't constants or subclasses of AR
|
476
|
+
@class_names.delete_if do |klass_name, klass|
|
477
|
+
!insert_class(@class_names, klass_name, klass)
|
478
|
+
end
|
479
|
+
end
|
437
480
|
|
438
|
-
|
439
|
-
|
440
|
-
|
481
|
+
def [](fs_name)
|
482
|
+
@class_names.fetch(fs_name) do
|
483
|
+
klass = default_fixture_model(fs_name, @config).safe_constantize
|
484
|
+
insert_class(@class_names, fs_name, klass)
|
485
|
+
end
|
486
|
+
end
|
441
487
|
|
442
|
-
|
443
|
-
|
488
|
+
private
|
489
|
+
def insert_class(class_names, name, klass)
|
490
|
+
# We only want to deal with AR objects.
|
491
|
+
if klass && klass < ActiveRecord::Base
|
492
|
+
class_names[name] = klass
|
493
|
+
else
|
494
|
+
class_names[name] = nil
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
def default_fixture_model(fs_name, config)
|
499
|
+
ActiveRecord::FixtureSet.default_fixture_model_name(fs_name, config)
|
500
|
+
end
|
444
501
|
end
|
445
502
|
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
503
|
+
class << self
|
504
|
+
def default_fixture_model_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc:
|
505
|
+
config.pluralize_table_names ?
|
506
|
+
fixture_set_name.singularize.camelize :
|
507
|
+
fixture_set_name.camelize
|
451
508
|
end
|
452
|
-
end
|
453
509
|
|
454
|
-
|
455
|
-
|
456
|
-
|
510
|
+
def default_fixture_table_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc:
|
511
|
+
"#{ config.table_name_prefix }"\
|
512
|
+
"#{ fixture_set_name.tr('/', '_') }"\
|
513
|
+
"#{ config.table_name_suffix }".to_sym
|
514
|
+
end
|
457
515
|
|
458
|
-
|
459
|
-
|
460
|
-
fixture_set.each do |fixture_name, fixture|
|
461
|
-
begin
|
462
|
-
object.instance_variable_set "@#{fixture_name}", fixture.find
|
463
|
-
rescue FixtureClassNotFound
|
464
|
-
nil
|
465
|
-
end
|
466
|
-
end
|
516
|
+
def reset_cache
|
517
|
+
@@all_cached_fixtures.clear
|
467
518
|
end
|
468
|
-
end
|
469
519
|
|
470
|
-
|
471
|
-
|
472
|
-
instantiate_fixtures(object, fixture_set, load_instances)
|
520
|
+
def cache_for_connection(connection)
|
521
|
+
@@all_cached_fixtures[connection]
|
473
522
|
end
|
474
|
-
end
|
475
523
|
|
476
|
-
|
477
|
-
|
524
|
+
def fixture_is_cached?(connection, table_name)
|
525
|
+
cache_for_connection(connection)[table_name]
|
526
|
+
end
|
478
527
|
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
528
|
+
def cached_fixtures(connection, keys_to_fetch = nil)
|
529
|
+
if keys_to_fetch
|
530
|
+
cache_for_connection(connection).values_at(*keys_to_fetch)
|
531
|
+
else
|
532
|
+
cache_for_connection(connection).values
|
533
|
+
end
|
534
|
+
end
|
483
535
|
|
484
|
-
|
485
|
-
|
536
|
+
def cache_fixtures(connection, fixtures_map)
|
537
|
+
cache_for_connection(connection).update(fixtures_map)
|
486
538
|
end
|
487
539
|
|
488
|
-
def
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
540
|
+
def instantiate_fixtures(object, fixture_set, load_instances = true)
|
541
|
+
return unless load_instances
|
542
|
+
fixture_set.each do |fixture_name, fixture|
|
543
|
+
object.instance_variable_set "@#{fixture_name}", fixture.find
|
544
|
+
rescue FixtureClassNotFound
|
545
|
+
nil
|
546
|
+
end
|
493
547
|
end
|
494
548
|
|
495
|
-
|
549
|
+
def instantiate_all_loaded_fixtures(object, load_instances = true)
|
550
|
+
all_loaded_fixtures.each_value do |fixture_set|
|
551
|
+
instantiate_fixtures(object, fixture_set, load_instances)
|
552
|
+
end
|
553
|
+
end
|
496
554
|
|
497
|
-
def
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
555
|
+
def create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base, &block)
|
556
|
+
fixture_set_names = Array(fixture_set_names).map(&:to_s)
|
557
|
+
class_names = ClassCache.new class_names, config
|
558
|
+
|
559
|
+
# FIXME: Apparently JK uses this.
|
560
|
+
connection = block_given? ? block : lambda { ActiveRecord::Base.connection }
|
561
|
+
|
562
|
+
fixture_files_to_read = fixture_set_names.reject do |fs_name|
|
563
|
+
fixture_is_cached?(connection.call, fs_name)
|
564
|
+
end
|
565
|
+
|
566
|
+
if fixture_files_to_read.any?
|
567
|
+
fixtures_map = read_and_insert(
|
568
|
+
fixtures_directory,
|
569
|
+
fixture_files_to_read,
|
570
|
+
class_names,
|
571
|
+
connection,
|
572
|
+
)
|
573
|
+
cache_fixtures(connection.call, fixtures_map)
|
503
574
|
end
|
575
|
+
cached_fixtures(connection.call, fixture_set_names)
|
504
576
|
end
|
505
577
|
|
506
|
-
|
507
|
-
|
578
|
+
# Returns a consistent, platform-independent identifier for +label+.
|
579
|
+
# Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes.
|
580
|
+
def identify(label, column_type = :integer)
|
581
|
+
if column_type == :uuid
|
582
|
+
Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, label.to_s)
|
583
|
+
else
|
584
|
+
Zlib.crc32(label.to_s) % MAX_ID
|
585
|
+
end
|
508
586
|
end
|
509
|
-
end
|
510
587
|
|
511
|
-
|
512
|
-
|
513
|
-
|
588
|
+
def signed_global_id(fixture_set_name, label, column_type: :integer, **options)
|
589
|
+
identifier = identify(label, column_type)
|
590
|
+
model_name = default_fixture_model_name(fixture_set_name)
|
591
|
+
uri = URI::GID.build([GlobalID.app, model_name, identifier, {}])
|
514
592
|
|
515
|
-
|
516
|
-
|
593
|
+
SignedGlobalID.new(uri, **options)
|
594
|
+
end
|
517
595
|
|
518
|
-
|
519
|
-
|
520
|
-
|
596
|
+
# Superclass for the evaluation contexts used by ERB fixtures.
|
597
|
+
def context_class
|
598
|
+
@context_class ||= Class.new
|
599
|
+
end
|
521
600
|
|
522
|
-
|
523
|
-
connection
|
601
|
+
private
|
602
|
+
def read_and_insert(fixtures_directory, fixture_files, class_names, connection) # :nodoc:
|
524
603
|
fixtures_map = {}
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
conn,
|
531
|
-
fs_name,
|
604
|
+
fixture_sets = fixture_files.map do |fixture_set_name|
|
605
|
+
klass = class_names[fixture_set_name]
|
606
|
+
fixtures_map[fixture_set_name] = new( # ActiveRecord::FixtureSet.new
|
607
|
+
nil,
|
608
|
+
fixture_set_name,
|
532
609
|
klass,
|
533
|
-
::File.join(fixtures_directory,
|
610
|
+
::File.join(fixtures_directory, fixture_set_name)
|
611
|
+
)
|
534
612
|
end
|
613
|
+
update_all_loaded_fixtures(fixtures_map)
|
535
614
|
|
536
|
-
|
615
|
+
insert(fixture_sets, connection)
|
537
616
|
|
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
|
617
|
+
fixtures_map
|
618
|
+
end
|
543
619
|
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
620
|
+
def insert(fixture_sets, connection) # :nodoc:
|
621
|
+
fixture_sets_by_connection = fixture_sets.group_by do |fixture_set|
|
622
|
+
if fixture_set.model_class
|
623
|
+
fixture_set.model_class.connection
|
624
|
+
else
|
625
|
+
connection.call
|
626
|
+
end
|
627
|
+
end
|
550
628
|
|
551
|
-
|
552
|
-
|
553
|
-
conn.insert_fixture(row, fixture_set_name)
|
554
|
-
end
|
555
|
-
end
|
629
|
+
fixture_sets_by_connection.each do |conn, set|
|
630
|
+
table_rows_for_connection = Hash.new { |h, k| h[k] = [] }
|
556
631
|
|
557
|
-
|
558
|
-
|
559
|
-
|
632
|
+
set.each do |fixture_set|
|
633
|
+
fixture_set.table_rows.each do |table, rows|
|
634
|
+
table_rows_for_connection[table].unshift(*rows)
|
560
635
|
end
|
561
636
|
end
|
562
|
-
end
|
563
637
|
|
564
|
-
|
565
|
-
end
|
566
|
-
end
|
567
|
-
cached_fixtures(connection, fixture_set_names)
|
568
|
-
end
|
638
|
+
conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys)
|
569
639
|
|
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
|
640
|
+
# Cap primary key sequences to max(pk).
|
641
|
+
if conn.respond_to?(:reset_pk_sequence!)
|
642
|
+
set.each { |fs| conn.reset_pk_sequence!(fs.table_name) }
|
643
|
+
end
|
644
|
+
end
|
645
|
+
end
|
584
646
|
|
585
|
-
|
586
|
-
|
647
|
+
def update_all_loaded_fixtures(fixtures_map) # :nodoc:
|
648
|
+
all_loaded_fixtures.update(fixtures_map)
|
649
|
+
end
|
587
650
|
end
|
588
651
|
|
589
|
-
attr_reader :table_name, :name, :fixtures, :model_class, :config
|
652
|
+
attr_reader :table_name, :name, :fixtures, :model_class, :ignored_fixtures, :config
|
590
653
|
|
591
|
-
def initialize(
|
654
|
+
def initialize(_, name, class_name, path, config = ActiveRecord::Base)
|
592
655
|
@name = name
|
593
656
|
@path = path
|
594
657
|
@config = config
|
@@ -597,18 +660,14 @@ module ActiveRecord
|
|
597
660
|
|
598
661
|
@fixtures = read_fixture_files(path)
|
599
662
|
|
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) )
|
663
|
+
@table_name = model_class&.table_name || self.class.default_fixture_table_name(name, config)
|
605
664
|
end
|
606
665
|
|
607
666
|
def [](x)
|
608
667
|
fixtures[x]
|
609
668
|
end
|
610
669
|
|
611
|
-
def []=(k,v)
|
670
|
+
def []=(k, v)
|
612
671
|
fixtures[k] = v
|
613
672
|
end
|
614
673
|
|
@@ -623,153 +682,18 @@ module ActiveRecord
|
|
623
682
|
# Returns a hash of rows to be inserted. The key is the table, the value is
|
624
683
|
# a list of rows to insert to that table.
|
625
684
|
def table_rows
|
626
|
-
|
627
|
-
|
628
|
-
# allow a standard key to be used for doing defaults in YAML
|
629
|
-
fixtures.delete('DEFAULTS')
|
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
|
685
|
+
# allow specifying fixtures to be ignored by setting `ignore` in `_fixture` section
|
686
|
+
fixtures.except!(*ignored_fixtures)
|
644
687
|
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
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
|
715
|
-
|
716
|
-
class HasManyThroughProxy < ReflectionProxy # :nodoc:
|
717
|
-
def rhs_key
|
718
|
-
@association.foreign_key
|
719
|
-
end
|
720
|
-
|
721
|
-
def lhs_key
|
722
|
-
@association.through_reflection.foreign_key
|
723
|
-
end
|
724
|
-
|
725
|
-
def join_table
|
726
|
-
@association.through_reflection.table_name
|
727
|
-
end
|
688
|
+
TableRows.new(
|
689
|
+
table_name,
|
690
|
+
model_class: model_class,
|
691
|
+
fixtures: fixtures,
|
692
|
+
config: config,
|
693
|
+
).to_hash
|
728
694
|
end
|
729
695
|
|
730
696
|
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
|
-
|
773
697
|
def model_class=(class_name)
|
774
698
|
if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
|
775
699
|
@model_class = class_name
|
@@ -778,6 +702,21 @@ module ActiveRecord
|
|
778
702
|
end
|
779
703
|
end
|
780
704
|
|
705
|
+
def ignored_fixtures=(base)
|
706
|
+
@ignored_fixtures =
|
707
|
+
case base
|
708
|
+
when Array
|
709
|
+
base
|
710
|
+
when String
|
711
|
+
[base]
|
712
|
+
else
|
713
|
+
[]
|
714
|
+
end
|
715
|
+
|
716
|
+
@ignored_fixtures << "DEFAULTS" unless @ignored_fixtures.include?("DEFAULTS")
|
717
|
+
@ignored_fixtures.compact
|
718
|
+
end
|
719
|
+
|
781
720
|
# Loads the fixtures from the YAML file at +path+.
|
782
721
|
# If the file sets the +model_class+ and current instance value is not set,
|
783
722
|
# it uses the file value.
|
@@ -789,6 +728,7 @@ module ActiveRecord
|
|
789
728
|
yaml_files.each_with_object({}) do |file, fixtures|
|
790
729
|
FixtureSet::File.open(file) do |fh|
|
791
730
|
self.model_class ||= fh.model_class if fh.model_class
|
731
|
+
self.ignored_fixtures ||= fh.ignored_fixtures
|
792
732
|
fh.each do |fixture_name, row|
|
793
733
|
fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
|
794
734
|
end
|
@@ -799,7 +739,6 @@ module ActiveRecord
|
|
799
739
|
def yaml_file_path(path)
|
800
740
|
"#{path}.yml"
|
801
741
|
end
|
802
|
-
|
803
742
|
end
|
804
743
|
|
805
744
|
class Fixture #:nodoc:
|
@@ -833,213 +772,13 @@ module ActiveRecord
|
|
833
772
|
alias :to_hash :fixture
|
834
773
|
|
835
774
|
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()
|
775
|
+
raise FixtureClassNotFound, "No class attached to find." unless model_class
|
776
|
+
object = model_class.unscoped do
|
777
|
+
model_class.find(fixture[model_class.primary_key])
|
1042
778
|
end
|
779
|
+
# Fixtures can't be eagerly loaded
|
780
|
+
object.instance_variable_set(:@strict_loading, false)
|
781
|
+
object
|
1043
782
|
end
|
1044
783
|
end
|
1045
784
|
end
|