activerecord 4.2.0 → 6.0.0
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 +612 -971
- data/MIT-LICENSE +4 -2
- data/README.rdoc +13 -12
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +267 -248
- data/lib/active_record/association_relation.rb +24 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +135 -56
- data/lib/active_record/associations/association_scope.rb +103 -131
- data/lib/active_record/associations/belongs_to_association.rb +67 -54
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +27 -40
- data/lib/active_record/associations/builder/belongs_to.rb +69 -55
- data/lib/active_record/associations/builder/collection_association.rb +10 -29
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +60 -70
- data/lib/active_record/associations/builder/has_many.rb +8 -4
- data/lib/active_record/associations/builder/has_one.rb +46 -5
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +138 -274
- data/lib/active_record/associations/collection_proxy.rb +252 -151
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +35 -83
- data/lib/active_record/associations/has_many_through_association.rb +62 -80
- data/lib/active_record/associations/has_one_association.rb +62 -49
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -80
- 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/join_dependency.rb +138 -162
- data/lib/active_record/associations/preloader/association.rb +90 -119
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +92 -94
- data/lib/active_record/associations/singular_association.rb +18 -45
- data/lib/active_record/associations/through_association.rb +48 -23
- data/lib/active_record/associations.rb +1737 -1596
- data/lib/active_record/attribute_assignment.rb +56 -183
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +15 -5
- data/lib/active_record/attribute_methods/dirty.rb +174 -134
- data/lib/active_record/attribute_methods/primary_key.rb +91 -83
- data/lib/active_record/attribute_methods/query.rb +6 -5
- data/lib/active_record/attribute_methods/read.rb +20 -76
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
- data/lib/active_record/attribute_methods/write.rb +33 -55
- data/lib/active_record/attribute_methods.rb +124 -143
- data/lib/active_record/attributes.rb +214 -74
- data/lib/active_record/autosave_association.rb +115 -46
- data/lib/active_record/base.rb +60 -49
- data/lib/active_record/callbacks.rb +100 -74
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -290
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +247 -108
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +366 -227
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +706 -222
- data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -87
- data/lib/active_record/connection_adapters/abstract_adapter.rb +468 -194
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +535 -597
- data/lib/active_record/connection_adapters/column.rb +56 -43
- data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -195
- data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +65 -115
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- 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 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- 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 +67 -51
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +474 -286
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -363
- data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- 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 +288 -359
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +176 -41
- data/lib/active_record/core.rb +266 -233
- data/lib/active_record/counter_cache.rb +68 -50
- 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 -105
- data/lib/active_record/enum.rb +164 -88
- data/lib/active_record/errors.rb +189 -53
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +35 -9
- 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 +226 -495
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +158 -112
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +123 -29
- data/lib/active_record/internal_metadata.rb +53 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +91 -98
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +76 -33
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +177 -90
- data/lib/active_record/migration/compatibility.rb +244 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +634 -288
- data/lib/active_record/model_schema.rb +314 -112
- data/lib/active_record/nested_attributes.rb +266 -214
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +559 -124
- data/lib/active_record/query_cache.rb +19 -23
- data/lib/active_record/querying.rb +43 -29
- data/lib/active_record/railtie.rb +148 -47
- 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 +338 -202
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +460 -299
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +207 -55
- data/lib/active_record/relation/calculations.rb +269 -248
- data/lib/active_record/relation/delegation.rb +70 -80
- data/lib/active_record/relation/finder_methods.rb +279 -255
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +83 -69
- data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +116 -92
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +574 -391
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -16
- data/lib/active_record/relation/where_clause.rb +190 -0
- data/lib/active_record/relation/where_clause_factory.rb +33 -0
- data/lib/active_record/relation.rb +518 -340
- data/lib/active_record/result.rb +79 -42
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +144 -121
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +112 -93
- data/lib/active_record/schema_migration.rb +24 -20
- data/lib/active_record/scoping/default.rb +101 -84
- data/lib/active_record/scoping/named.rb +86 -33
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +73 -36
- data/lib/active_record/store.rb +127 -42
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +75 -0
- data/lib/active_record/tasks/database_tasks.rb +309 -99
- data/lib/active_record/tasks/mysql_database_tasks.rb +58 -88
- data/lib/active_record/tasks/postgresql_database_tasks.rb +82 -31
- data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -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 +86 -40
- data/lib/active_record/touch_later.rb +66 -0
- data/lib/active_record/transactions.rb +215 -139
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +129 -0
- data/lib/active_record/type/date.rb +4 -41
- data/lib/active_record/type/date_time.rb +4 -38
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +30 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type.rb +78 -23
- data/lib/active_record/type_caster/connection.rb +34 -0
- data/lib/active_record/type_caster/map.rb +20 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +43 -46
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +43 -21
- 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 +51 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
- data/lib/rails/generators/active_record/migration.rb +31 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +166 -60
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- 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 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -149
- data/lib/active_record/attribute_set/builder.rb +0 -86
- data/lib/active_record/attribute_set.rb +0 -77
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -30
- data/lib/active_record/type/decimal.rb +0 -40
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -55
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -36
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -101
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,49 +1,41 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/conversions"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
module Associations
|
5
|
-
# Keeps track of table aliases for ActiveRecord::Associations::
|
6
|
-
# ActiveRecord::Associations::ThroughAssociationScope
|
7
|
+
# Keeps track of table aliases for ActiveRecord::Associations::JoinDependency
|
7
8
|
class AliasTracker # :nodoc:
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
new connection, Hash.new(0)
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.create(connection, table_joins)
|
15
|
-
if table_joins.empty?
|
16
|
-
empty connection
|
9
|
+
def self.create(connection, initial_table, joins)
|
10
|
+
if joins.empty?
|
11
|
+
aliases = Hash.new(0)
|
17
12
|
else
|
18
|
-
aliases = Hash.new { |h,k|
|
19
|
-
h[k] = initial_count_for(connection, k,
|
13
|
+
aliases = Hash.new { |h, k|
|
14
|
+
h[k] = initial_count_for(connection, k, joins)
|
20
15
|
}
|
21
|
-
new connection, aliases
|
22
16
|
end
|
17
|
+
aliases[initial_table] = 1
|
18
|
+
new(connection, aliases)
|
23
19
|
end
|
24
20
|
|
25
21
|
def self.initial_count_for(connection, name, table_joins)
|
26
|
-
|
27
|
-
quoted_name = connection.quote_table_name(name).downcase
|
22
|
+
quoted_name = nil
|
28
23
|
|
29
24
|
counts = table_joins.map do |join|
|
30
25
|
if join.is_a?(Arel::Nodes::StringJoin)
|
26
|
+
# quoted_name should be case ignored as some database adapters (Oracle) return quoted name in uppercase
|
27
|
+
quoted_name ||= connection.quote_table_name(name)
|
28
|
+
|
31
29
|
# Table names + table aliases
|
32
|
-
join.left.
|
33
|
-
/
|
30
|
+
join.left.scan(
|
31
|
+
/JOIN(?:\s+\w+)?\s+(?:\S+\s+)?(?:#{quoted_name}|#{name})\sON/i
|
34
32
|
).size
|
35
|
-
elsif join.
|
36
|
-
join.left.
|
33
|
+
elsif join.is_a?(Arel::Nodes::Join)
|
34
|
+
join.left.name == name ? 1 : 0
|
35
|
+
elsif join.is_a?(Hash)
|
36
|
+
join[name]
|
37
37
|
else
|
38
|
-
|
39
|
-
#
|
40
|
-
# activerecord/test/cases/associations/cascaded_eager_loading_test.rb:37
|
41
|
-
# with :posts
|
42
|
-
#
|
43
|
-
# activerecord/test/cases/associations/eager_test.rb:1133
|
44
|
-
# with :comments
|
45
|
-
#
|
46
|
-
0
|
38
|
+
raise ArgumentError, "joins list should be initialized by list of Arel::Nodes::Join"
|
47
39
|
end
|
48
40
|
end
|
49
41
|
|
@@ -56,14 +48,14 @@ module ActiveRecord
|
|
56
48
|
@connection = connection
|
57
49
|
end
|
58
50
|
|
59
|
-
def aliased_table_for(table_name, aliased_name)
|
51
|
+
def aliased_table_for(table_name, aliased_name, type_caster)
|
60
52
|
if aliases[table_name].zero?
|
61
53
|
# If it's zero, we can have our table_name
|
62
54
|
aliases[table_name] = 1
|
63
|
-
Arel::Table.new(table_name)
|
55
|
+
Arel::Table.new(table_name, type_caster: type_caster)
|
64
56
|
else
|
65
57
|
# Otherwise, we need to use an alias
|
66
|
-
aliased_name = connection.table_alias_for(aliased_name)
|
58
|
+
aliased_name = @connection.table_alias_for(aliased_name)
|
67
59
|
|
68
60
|
# Update the count
|
69
61
|
aliases[aliased_name] += 1
|
@@ -73,14 +65,16 @@ module ActiveRecord
|
|
73
65
|
else
|
74
66
|
aliased_name
|
75
67
|
end
|
76
|
-
Arel::Table.new(table_name).alias(table_alias)
|
68
|
+
Arel::Table.new(table_name, type_caster: type_caster).alias(table_alias)
|
77
69
|
end
|
78
70
|
end
|
79
71
|
|
72
|
+
attr_reader :aliases
|
73
|
+
|
80
74
|
private
|
81
75
|
|
82
76
|
def truncate(name)
|
83
|
-
name.slice(0, connection.table_alias_length - 2)
|
77
|
+
name.slice(0, @connection.table_alias_length - 2)
|
84
78
|
end
|
85
79
|
end
|
86
80
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/array/wrap"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
module Associations
|
@@ -8,18 +10,34 @@ module ActiveRecord
|
|
8
10
|
#
|
9
11
|
# Association
|
10
12
|
# SingularAssociation
|
11
|
-
# HasOneAssociation
|
13
|
+
# HasOneAssociation + ForeignAssociation
|
12
14
|
# HasOneThroughAssociation + ThroughAssociation
|
13
15
|
# BelongsToAssociation
|
14
16
|
# BelongsToPolymorphicAssociation
|
15
17
|
# CollectionAssociation
|
16
|
-
# HasManyAssociation
|
18
|
+
# HasManyAssociation + ForeignAssociation
|
17
19
|
# HasManyThroughAssociation + ThroughAssociation
|
20
|
+
#
|
21
|
+
# Associations in Active Record are middlemen between the object that
|
22
|
+
# holds the association, known as the <tt>owner</tt>, and the associated
|
23
|
+
# result set, known as the <tt>target</tt>. Association metadata is available in
|
24
|
+
# <tt>reflection</tt>, which is an instance of <tt>ActiveRecord::Reflection::AssociationReflection</tt>.
|
25
|
+
#
|
26
|
+
# For example, given
|
27
|
+
#
|
28
|
+
# class Blog < ActiveRecord::Base
|
29
|
+
# has_many :posts
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# blog = Blog.first
|
33
|
+
#
|
34
|
+
# The association of <tt>blog.posts</tt> has the object +blog+ as its
|
35
|
+
# <tt>owner</tt>, the collection of its posts as <tt>target</tt>, and
|
36
|
+
# the <tt>reflection</tt> object represents a <tt>:has_many</tt> macro.
|
18
37
|
class Association #:nodoc:
|
19
38
|
attr_reader :owner, :target, :reflection
|
20
|
-
attr_accessor :inversed
|
21
39
|
|
22
|
-
delegate :options, :
|
40
|
+
delegate :options, to: :reflection
|
23
41
|
|
24
42
|
def initialize(owner, reflection)
|
25
43
|
reflection.check_validity!
|
@@ -30,14 +48,6 @@ module ActiveRecord
|
|
30
48
|
reset_scope
|
31
49
|
end
|
32
50
|
|
33
|
-
# Returns the name of the table of the associated class:
|
34
|
-
#
|
35
|
-
# post.comments.aliased_table_name # => "comments"
|
36
|
-
#
|
37
|
-
def aliased_table_name
|
38
|
-
klass.table_name
|
39
|
-
end
|
40
|
-
|
41
51
|
# Resets the \loaded flag to +false+ and sets the \target to +nil+.
|
42
52
|
def reset
|
43
53
|
@loaded = false
|
@@ -47,7 +57,9 @@ module ActiveRecord
|
|
47
57
|
end
|
48
58
|
|
49
59
|
# Reloads the \target and returns +self+ on success.
|
50
|
-
|
60
|
+
# The QueryCache is cleared if +force+ is true.
|
61
|
+
def reload(force = false)
|
62
|
+
klass.connection.clear_query_cache if force && klass
|
51
63
|
reset
|
52
64
|
reset_scope
|
53
65
|
load_target
|
@@ -73,7 +85,7 @@ module ActiveRecord
|
|
73
85
|
#
|
74
86
|
# Note that if the target has not been loaded, it is not considered stale.
|
75
87
|
def stale_target?
|
76
|
-
|
88
|
+
!@inversed && loaded? && @stale_state != stale_state
|
77
89
|
end
|
78
90
|
|
79
91
|
# Sets the target of this association to <tt>\target</tt>, and the \loaded flag to +true+.
|
@@ -83,19 +95,7 @@ module ActiveRecord
|
|
83
95
|
end
|
84
96
|
|
85
97
|
def scope
|
86
|
-
target_scope.merge(association_scope)
|
87
|
-
end
|
88
|
-
|
89
|
-
# The scope for this association.
|
90
|
-
#
|
91
|
-
# Note that the association_scope is merged into the target_scope only when the
|
92
|
-
# scope method is called. This is because at that point the call may be surrounded
|
93
|
-
# by scope.scoping { ... } or with_scope { ... } etc, which affects the scope which
|
94
|
-
# actually gets built.
|
95
|
-
def association_scope
|
96
|
-
if klass
|
97
|
-
@association_scope ||= AssociationScope.scope(self, klass.connection)
|
98
|
-
end
|
98
|
+
target_scope.merge!(association_scope)
|
99
99
|
end
|
100
100
|
|
101
101
|
def reset_scope
|
@@ -104,24 +104,46 @@ module ActiveRecord
|
|
104
104
|
|
105
105
|
# Set the inverse association, if possible
|
106
106
|
def set_inverse_instance(record)
|
107
|
-
if
|
108
|
-
inverse
|
109
|
-
|
110
|
-
|
107
|
+
if inverse = inverse_association_for(record)
|
108
|
+
inverse.inversed_from(owner)
|
109
|
+
end
|
110
|
+
record
|
111
|
+
end
|
112
|
+
|
113
|
+
def set_inverse_instance_from_queries(record)
|
114
|
+
if inverse = inverse_association_for(record)
|
115
|
+
inverse.inversed_from_queries(owner)
|
111
116
|
end
|
112
117
|
record
|
113
118
|
end
|
114
119
|
|
120
|
+
# Remove the inverse association, if possible
|
121
|
+
def remove_inverse_instance(record)
|
122
|
+
if inverse = inverse_association_for(record)
|
123
|
+
inverse.inversed_from(nil)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def inversed_from(record)
|
128
|
+
self.target = record
|
129
|
+
@inversed = !!record
|
130
|
+
end
|
131
|
+
alias :inversed_from_queries :inversed_from
|
132
|
+
|
115
133
|
# Returns the class of the target. belongs_to polymorphic overrides this to look at the
|
116
134
|
# polymorphic_type field on the owner.
|
117
135
|
def klass
|
118
136
|
reflection.klass
|
119
137
|
end
|
120
138
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
139
|
+
def extensions
|
140
|
+
extensions = klass.default_extensions | reflection.extensions
|
141
|
+
|
142
|
+
if reflection.scope
|
143
|
+
extensions |= reflection.scope_for(klass.unscoped, owner).extensions
|
144
|
+
end
|
145
|
+
|
146
|
+
extensions
|
125
147
|
end
|
126
148
|
|
127
149
|
# Loads the \target if needed and returns it.
|
@@ -143,17 +165,9 @@ module ActiveRecord
|
|
143
165
|
reset
|
144
166
|
end
|
145
167
|
|
146
|
-
|
147
|
-
if sql.respond_to?(:to_proc)
|
148
|
-
owner.instance_exec(record, &sql)
|
149
|
-
else
|
150
|
-
sql
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
# We can't dump @reflection since it contains the scope proc
|
168
|
+
# We can't dump @reflection and @through_reflection since it contains the scope proc
|
155
169
|
def marshal_dump
|
156
|
-
ivars = (instance_variables - [:@reflection]).map { |name| [name, instance_variable_get(name)] }
|
170
|
+
ivars = (instance_variables - [:@reflection, :@through_reflection]).map { |name| [name, instance_variable_get(name)] }
|
157
171
|
[@reflection.name, ivars]
|
158
172
|
end
|
159
173
|
|
@@ -163,14 +177,60 @@ module ActiveRecord
|
|
163
177
|
@reflection = @owner.class._reflect_on_association(reflection_name)
|
164
178
|
end
|
165
179
|
|
166
|
-
def initialize_attributes(record) #:nodoc:
|
180
|
+
def initialize_attributes(record, except_from_scope_attributes = nil) #:nodoc:
|
181
|
+
except_from_scope_attributes ||= {}
|
167
182
|
skip_assign = [reflection.foreign_key, reflection.type].compact
|
168
|
-
|
169
|
-
|
183
|
+
assigned_keys = record.changed_attribute_names_to_save
|
184
|
+
assigned_keys += except_from_scope_attributes.keys.map(&:to_s)
|
185
|
+
attributes = scope_for_create.except!(*(assigned_keys - skip_assign))
|
186
|
+
record.send(:_assign_attributes, attributes) if attributes.any?
|
170
187
|
set_inverse_instance(record)
|
171
188
|
end
|
172
189
|
|
190
|
+
def create(attributes = {}, &block)
|
191
|
+
_create_record(attributes, &block)
|
192
|
+
end
|
193
|
+
|
194
|
+
def create!(attributes = {}, &block)
|
195
|
+
_create_record(attributes, true, &block)
|
196
|
+
end
|
197
|
+
|
173
198
|
private
|
199
|
+
def find_target
|
200
|
+
scope = self.scope
|
201
|
+
return scope.to_a if skip_statement_cache?(scope)
|
202
|
+
|
203
|
+
conn = klass.connection
|
204
|
+
sc = reflection.association_scope_cache(conn, owner) do |params|
|
205
|
+
as = AssociationScope.create { params.bind }
|
206
|
+
target_scope.merge!(as.scope(self))
|
207
|
+
end
|
208
|
+
|
209
|
+
binds = AssociationScope.get_bind_values(owner, reflection.chain)
|
210
|
+
sc.execute(binds, conn) { |record| set_inverse_instance(record) } || []
|
211
|
+
end
|
212
|
+
|
213
|
+
# The scope for this association.
|
214
|
+
#
|
215
|
+
# Note that the association_scope is merged into the target_scope only when the
|
216
|
+
# scope method is called. This is because at that point the call may be surrounded
|
217
|
+
# by scope.scoping { ... } or unscoped { ... } etc, which affects the scope which
|
218
|
+
# actually gets built.
|
219
|
+
def association_scope
|
220
|
+
if klass
|
221
|
+
@association_scope ||= AssociationScope.scope(self)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
|
226
|
+
# through association's scope)
|
227
|
+
def target_scope
|
228
|
+
AssociationRelation.create(klass, self).merge!(klass.scope_for_association)
|
229
|
+
end
|
230
|
+
|
231
|
+
def scope_for_create
|
232
|
+
scope.scope_for_create
|
233
|
+
end
|
174
234
|
|
175
235
|
def find_target?
|
176
236
|
!loaded? && (!owner.new_record? || foreign_key_present?) && klass
|
@@ -182,8 +242,8 @@ module ActiveRecord
|
|
182
242
|
if (reflection.has_one? || reflection.collection?) && !options[:through]
|
183
243
|
attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
|
184
244
|
|
185
|
-
if reflection.
|
186
|
-
attributes[reflection.type] = owner.class.
|
245
|
+
if reflection.type
|
246
|
+
attributes[reflection.type] = owner.class.polymorphic_name
|
187
247
|
end
|
188
248
|
end
|
189
249
|
|
@@ -211,9 +271,19 @@ module ActiveRecord
|
|
211
271
|
# the kind of the class of the associated objects. Meant to be used as
|
212
272
|
# a sanity check when you are about to assign an associated record.
|
213
273
|
def raise_on_type_mismatch!(record)
|
214
|
-
unless record.is_a?(reflection.klass)
|
215
|
-
|
216
|
-
|
274
|
+
unless record.is_a?(reflection.klass)
|
275
|
+
fresh_class = reflection.class_name.safe_constantize
|
276
|
+
unless fresh_class && record.is_a?(fresh_class)
|
277
|
+
message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, "\
|
278
|
+
"got #{record.inspect} which is an instance of #{record.class}(##{record.class.object_id})"
|
279
|
+
raise ActiveRecord::AssociationTypeMismatch, message
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def inverse_association_for(record)
|
285
|
+
if invertible_for?(record)
|
286
|
+
record.association(inverse_reflection_for(record).name)
|
217
287
|
end
|
218
288
|
end
|
219
289
|
|
@@ -239,15 +309,24 @@ module ActiveRecord
|
|
239
309
|
# so that when stale_state is different from the value stored on the last find_target,
|
240
310
|
# the target is stale.
|
241
311
|
#
|
242
|
-
# This is only relevant to certain associations, which is why it returns nil by default.
|
312
|
+
# This is only relevant to certain associations, which is why it returns +nil+ by default.
|
243
313
|
def stale_state
|
244
314
|
end
|
245
315
|
|
246
316
|
def build_record(attributes)
|
247
317
|
reflection.build_association(attributes) do |record|
|
248
|
-
initialize_attributes(record)
|
318
|
+
initialize_attributes(record, attributes)
|
319
|
+
yield(record) if block_given?
|
249
320
|
end
|
250
321
|
end
|
322
|
+
|
323
|
+
# Returns true if statement cache should be skipped on the association reader.
|
324
|
+
def skip_statement_cache?(scope)
|
325
|
+
reflection.has_scope? ||
|
326
|
+
scope.eager_loading? ||
|
327
|
+
klass.scope_attributes? ||
|
328
|
+
reflection.source_reflection.active_record.default_scopes.any?
|
329
|
+
end
|
251
330
|
end
|
252
331
|
end
|
253
332
|
end
|