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,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Associations
|
3
5
|
# Implements the details of eager loading of Active Record associations.
|
@@ -10,13 +12,13 @@ module ActiveRecord
|
|
10
12
|
# end
|
11
13
|
#
|
12
14
|
# class Book < ActiveRecord::Base
|
13
|
-
# # columns: title, sales
|
15
|
+
# # columns: title, sales, author_id
|
14
16
|
# end
|
15
17
|
#
|
16
18
|
# When you load an author with all associated books Active Record will make
|
17
19
|
# multiple queries like this:
|
18
20
|
#
|
19
|
-
# Author.includes(:books).where(:
|
21
|
+
# Author.includes(:books).where(name: ['bell hooks', 'Homer']).to_a
|
20
22
|
#
|
21
23
|
# => SELECT `authors`.* FROM `authors` WHERE `name` IN ('bell hooks', 'Homer')
|
22
24
|
# => SELECT `books`.* FROM `books` WHERE `author_id` IN (2, 5)
|
@@ -42,16 +44,8 @@ module ActiveRecord
|
|
42
44
|
extend ActiveSupport::Autoload
|
43
45
|
|
44
46
|
eager_autoload do
|
45
|
-
autoload :Association,
|
46
|
-
autoload :
|
47
|
-
autoload :CollectionAssociation, 'active_record/associations/preloader/collection_association'
|
48
|
-
autoload :ThroughAssociation, 'active_record/associations/preloader/through_association'
|
49
|
-
|
50
|
-
autoload :HasMany, 'active_record/associations/preloader/has_many'
|
51
|
-
autoload :HasManyThrough, 'active_record/associations/preloader/has_many_through'
|
52
|
-
autoload :HasOne, 'active_record/associations/preloader/has_one'
|
53
|
-
autoload :HasOneThrough, 'active_record/associations/preloader/has_one_through'
|
54
|
-
autoload :BelongsTo, 'active_record/associations/preloader/belongs_to'
|
47
|
+
autoload :Association, "active_record/associations/preloader/association"
|
48
|
+
autoload :ThroughAssociation, "active_record/associations/preloader/through_association"
|
55
49
|
end
|
56
50
|
|
57
51
|
# Eager loads the named associations for the given Active Record record(s).
|
@@ -88,18 +82,13 @@ module ActiveRecord
|
|
88
82
|
# [ :books, :author ]
|
89
83
|
# { author: :avatar }
|
90
84
|
# [ :books, { author: :avatar } ]
|
91
|
-
|
92
|
-
NULL_RELATION = Struct.new(:values, :bind_values).new({}, [])
|
93
|
-
|
94
85
|
def preload(records, associations, preload_scope = nil)
|
95
|
-
records
|
96
|
-
associations = Array.wrap(associations)
|
97
|
-
preload_scope = preload_scope || NULL_RELATION
|
86
|
+
records = Array.wrap(records).compact
|
98
87
|
|
99
88
|
if records.empty?
|
100
89
|
[]
|
101
90
|
else
|
102
|
-
associations.flat_map { |association|
|
91
|
+
Array.wrap(associations).flat_map { |association|
|
103
92
|
preloaders_on association, records, preload_scope
|
104
93
|
}
|
105
94
|
end
|
@@ -107,97 +96,106 @@ module ActiveRecord
|
|
107
96
|
|
108
97
|
private
|
109
98
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
99
|
+
# Loads all the given data into +records+ for the +association+.
|
100
|
+
def preloaders_on(association, records, scope, polymorphic_parent = false)
|
101
|
+
case association
|
102
|
+
when Hash
|
103
|
+
preloaders_for_hash(association, records, scope, polymorphic_parent)
|
104
|
+
when Symbol, String
|
105
|
+
preloaders_for_one(association, records, scope, polymorphic_parent)
|
106
|
+
else
|
107
|
+
raise ArgumentError, "#{association.inspect} was not recognized for preload"
|
108
|
+
end
|
120
109
|
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def preloaders_for_hash(association, records, scope)
|
124
|
-
association.flat_map { |parent, child|
|
125
|
-
loaders = preloaders_for_one parent, records, scope
|
126
110
|
|
127
|
-
|
128
|
-
|
129
|
-
|
111
|
+
def preloaders_for_hash(association, records, scope, polymorphic_parent)
|
112
|
+
association.flat_map { |parent, child|
|
113
|
+
grouped_records(parent, records, polymorphic_parent).flat_map do |reflection, reflection_records|
|
114
|
+
loaders = preloaders_for_reflection(reflection, reflection_records, scope)
|
115
|
+
recs = loaders.flat_map(&:preloaded_records)
|
116
|
+
child_polymorphic_parent = reflection && reflection.options[:polymorphic]
|
117
|
+
loaders.concat Array.wrap(child).flat_map { |assoc|
|
118
|
+
preloaders_on assoc, recs, scope, child_polymorphic_parent
|
119
|
+
}
|
120
|
+
loaders
|
121
|
+
end
|
130
122
|
}
|
131
|
-
loaders
|
132
|
-
}
|
133
|
-
end
|
134
|
-
|
135
|
-
# Not all records have the same class, so group then preload group on the reflection
|
136
|
-
# itself so that if various subclass share the same association then we do not split
|
137
|
-
# them unnecessarily
|
138
|
-
#
|
139
|
-
# Additionally, polymorphic belongs_to associations can have multiple associated
|
140
|
-
# classes, depending on the polymorphic_type field. So we group by the classes as
|
141
|
-
# well.
|
142
|
-
def preloaders_for_one(association, records, scope)
|
143
|
-
grouped_records(association, records).flat_map do |reflection, klasses|
|
144
|
-
klasses.map do |rhs_klass, rs|
|
145
|
-
loader = preloader_for(reflection, rs, rhs_klass).new(rhs_klass, rs, reflection, scope)
|
146
|
-
loader.run self
|
147
|
-
loader
|
148
|
-
end
|
149
123
|
end
|
150
|
-
end
|
151
124
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
125
|
+
# Loads all the given data into +records+ for a singular +association+.
|
126
|
+
#
|
127
|
+
# Functions by instantiating a preloader class such as Preloader::Association and
|
128
|
+
# call the +run+ method for each passed in class in the +records+ argument.
|
129
|
+
#
|
130
|
+
# Not all records have the same class, so group then preload group on the reflection
|
131
|
+
# itself so that if various subclass share the same association then we do not split
|
132
|
+
# them unnecessarily
|
133
|
+
#
|
134
|
+
# Additionally, polymorphic belongs_to associations can have multiple associated
|
135
|
+
# classes, depending on the polymorphic_type field. So we group by the classes as
|
136
|
+
# well.
|
137
|
+
def preloaders_for_one(association, records, scope, polymorphic_parent)
|
138
|
+
grouped_records(association, records, polymorphic_parent)
|
139
|
+
.flat_map do |reflection, reflection_records|
|
140
|
+
preloaders_for_reflection reflection, reflection_records, scope
|
141
|
+
end
|
159
142
|
end
|
160
|
-
h
|
161
|
-
end
|
162
143
|
|
163
|
-
|
164
|
-
|
144
|
+
def preloaders_for_reflection(reflection, records, scope)
|
145
|
+
records.group_by { |record| record.association(reflection.name).klass }.map do |rhs_klass, rs|
|
146
|
+
preloader_for(reflection, rs).new(rhs_klass, rs, reflection, scope).run
|
147
|
+
end
|
148
|
+
end
|
165
149
|
|
166
|
-
def
|
167
|
-
|
168
|
-
|
150
|
+
def grouped_records(association, records, polymorphic_parent)
|
151
|
+
h = {}
|
152
|
+
records.each do |record|
|
153
|
+
reflection = record.class._reflect_on_association(association)
|
154
|
+
next if polymorphic_parent && !reflection || !record.association(association).klass
|
155
|
+
(h[reflection] ||= []) << record
|
156
|
+
end
|
157
|
+
h
|
169
158
|
end
|
170
159
|
|
171
|
-
|
160
|
+
class AlreadyLoaded # :nodoc:
|
161
|
+
def initialize(klass, owners, reflection, preload_scope)
|
162
|
+
@owners = owners
|
163
|
+
@reflection = reflection
|
164
|
+
end
|
172
165
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
end
|
166
|
+
def run
|
167
|
+
self
|
168
|
+
end
|
177
169
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
def self.preloaded_records; []; end
|
182
|
-
end
|
170
|
+
def preloaded_records
|
171
|
+
@preloaded_records ||= records_by_owner.flat_map(&:last)
|
172
|
+
end
|
183
173
|
|
184
|
-
|
185
|
-
|
174
|
+
def records_by_owner
|
175
|
+
@records_by_owner ||= owners.each_with_object({}) do |owner, result|
|
176
|
+
result[owner] = Array(owner.association(reflection.name).target)
|
177
|
+
end
|
178
|
+
end
|
186
179
|
|
187
|
-
|
188
|
-
|
180
|
+
private
|
181
|
+
attr_reader :owners, :reflection
|
189
182
|
end
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
183
|
+
|
184
|
+
# Returns a class containing the logic needed to load preload the data
|
185
|
+
# and attach it to a relation. The class returned implements a `run` method
|
186
|
+
# that accepts a preloader.
|
187
|
+
def preloader_for(reflection, owners)
|
188
|
+
if owners.first.association(reflection.name).loaded?
|
189
|
+
return AlreadyLoaded
|
190
|
+
end
|
191
|
+
reflection.check_preloadable!
|
192
|
+
|
193
|
+
if reflection.options[:through]
|
194
|
+
ThroughAssociation
|
195
|
+
else
|
196
|
+
Association
|
197
|
+
end
|
199
198
|
end
|
200
|
-
end
|
201
199
|
end
|
202
200
|
end
|
203
201
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Associations
|
3
5
|
class SingularAssociation < Association #:nodoc:
|
4
6
|
# Implements the reader method, e.g. foo.bar for Foo.has_one :bar
|
5
|
-
def reader
|
6
|
-
if
|
7
|
-
klass.uncached { reload }
|
8
|
-
elsif !loaded? || stale_target?
|
7
|
+
def reader
|
8
|
+
if !loaded? || stale_target?
|
9
9
|
reload
|
10
10
|
end
|
11
11
|
|
@@ -17,52 +17,26 @@ module ActiveRecord
|
|
17
17
|
replace(record)
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def create!(attributes = {}, &block)
|
25
|
-
_create_record(attributes, true, &block)
|
26
|
-
end
|
27
|
-
|
28
|
-
def build(attributes = {})
|
29
|
-
record = build_record(attributes)
|
30
|
-
yield(record) if block_given?
|
20
|
+
def build(attributes = {}, &block)
|
21
|
+
record = build_record(attributes, &block)
|
31
22
|
set_new_record(record)
|
32
23
|
record
|
33
24
|
end
|
34
25
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
def get_records
|
42
|
-
if reflection.scope_chain.any?(&:any?) ||
|
43
|
-
scope.eager_loading? ||
|
44
|
-
klass.current_scope ||
|
45
|
-
klass.default_scopes.any?
|
46
|
-
|
47
|
-
return scope.limit(1).to_a
|
48
|
-
end
|
49
|
-
|
50
|
-
conn = klass.connection
|
51
|
-
sc = reflection.association_scope_cache(conn, owner) do
|
52
|
-
StatementCache.create(conn) { |params|
|
53
|
-
as = AssociationScope.create { params.bind }
|
54
|
-
target_scope.merge(as.scope(self, conn)).limit(1)
|
55
|
-
}
|
56
|
-
end
|
26
|
+
# Implements the reload reader method, e.g. foo.reload_bar for
|
27
|
+
# Foo.has_one :bar
|
28
|
+
def force_reload_reader
|
29
|
+
reload(true)
|
30
|
+
target
|
31
|
+
end
|
57
32
|
|
58
|
-
|
59
|
-
|
33
|
+
private
|
34
|
+
def scope_for_create
|
35
|
+
super.except!(klass.primary_key)
|
60
36
|
end
|
61
37
|
|
62
38
|
def find_target
|
63
|
-
|
64
|
-
set_inverse_instance record
|
65
|
-
end
|
39
|
+
super.first
|
66
40
|
end
|
67
41
|
|
68
42
|
def replace(record)
|
@@ -73,9 +47,8 @@ module ActiveRecord
|
|
73
47
|
replace(record)
|
74
48
|
end
|
75
49
|
|
76
|
-
def _create_record(attributes, raise_error = false)
|
77
|
-
record = build_record(attributes)
|
78
|
-
yield(record) if block_given?
|
50
|
+
def _create_record(attributes, raise_error = false, &block)
|
51
|
+
record = build_record(attributes, &block)
|
79
52
|
saved = record.save
|
80
53
|
set_new_record(record)
|
81
54
|
raise RecordInvalid.new(record) if !saved && raise_error
|
@@ -1,11 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# = Active Record Through Association
|
3
4
|
module Associations
|
5
|
+
# = Active Record Through Association
|
4
6
|
module ThroughAssociation #:nodoc:
|
7
|
+
delegate :source_reflection, to: :reflection
|
8
|
+
|
9
|
+
private
|
10
|
+
def through_reflection
|
11
|
+
@through_reflection ||= begin
|
12
|
+
refl = reflection.through_reflection
|
5
13
|
|
6
|
-
|
14
|
+
while refl.through_reflection?
|
15
|
+
refl = refl.through_reflection
|
16
|
+
end
|
7
17
|
|
8
|
-
|
18
|
+
refl
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def through_association
|
23
|
+
@through_association ||= owner.association(through_reflection.name)
|
24
|
+
end
|
9
25
|
|
10
26
|
# We merge in these scopes for two reasons:
|
11
27
|
#
|
@@ -14,13 +30,7 @@ module ActiveRecord
|
|
14
30
|
def target_scope
|
15
31
|
scope = super
|
16
32
|
reflection.chain.drop(1).each do |reflection|
|
17
|
-
relation = reflection.klass.
|
18
|
-
|
19
|
-
reflection_scope = reflection.scope
|
20
|
-
if reflection_scope && reflection_scope.arity.zero?
|
21
|
-
relation.merge!(reflection_scope)
|
22
|
-
end
|
23
|
-
|
33
|
+
relation = reflection.klass.scope_for_association
|
24
34
|
scope.merge!(
|
25
35
|
relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load)
|
26
36
|
)
|
@@ -28,12 +38,10 @@ module ActiveRecord
|
|
28
38
|
scope
|
29
39
|
end
|
30
40
|
|
31
|
-
private
|
32
|
-
|
33
41
|
# Construct attributes for :through pointing to owner and associate. This is used by the
|
34
42
|
# methods which create and delete records on the association.
|
35
43
|
#
|
36
|
-
# We only support indirectly modifying through associations which
|
44
|
+
# We only support indirectly modifying through associations which have a belongs_to source.
|
37
45
|
# This is the "has_many :tags, through: :taggings" situation, where the join model
|
38
46
|
# typically has a belongs_to on both side. In other words, associations which could also
|
39
47
|
# be represented as has_and_belongs_to_many associations.
|
@@ -45,24 +53,22 @@ module ActiveRecord
|
|
45
53
|
def construct_join_attributes(*records)
|
46
54
|
ensure_mutable
|
47
55
|
|
48
|
-
|
56
|
+
association_primary_key = source_reflection.association_primary_key(reflection.klass)
|
57
|
+
|
58
|
+
if association_primary_key == reflection.klass.primary_key && !options[:source_type]
|
49
59
|
join_attributes = { source_reflection.name => records }
|
50
60
|
else
|
51
61
|
join_attributes = {
|
52
|
-
source_reflection.foreign_key =>
|
53
|
-
records.map { |record|
|
54
|
-
record.send(source_reflection.association_primary_key(reflection.klass))
|
55
|
-
}
|
62
|
+
source_reflection.foreign_key => records.map(&association_primary_key.to_sym)
|
56
63
|
}
|
57
64
|
end
|
58
65
|
|
59
66
|
if options[:source_type]
|
60
|
-
join_attributes[source_reflection.foreign_type] =
|
61
|
-
records.map { |record| record.class.base_class.name }
|
67
|
+
join_attributes[source_reflection.foreign_type] = [ options[:source_type] ]
|
62
68
|
end
|
63
69
|
|
64
70
|
if records.count == 1
|
65
|
-
|
71
|
+
join_attributes.transform_values!(&:first)
|
66
72
|
else
|
67
73
|
join_attributes
|
68
74
|
end
|
@@ -82,15 +88,34 @@ module ActiveRecord
|
|
82
88
|
|
83
89
|
def ensure_mutable
|
84
90
|
unless source_reflection.belongs_to?
|
85
|
-
|
91
|
+
if reflection.has_one?
|
92
|
+
raise HasOneThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
|
93
|
+
else
|
94
|
+
raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
|
95
|
+
end
|
86
96
|
end
|
87
97
|
end
|
88
98
|
|
89
99
|
def ensure_not_nested
|
90
100
|
if reflection.nested?
|
91
|
-
|
101
|
+
if reflection.has_one?
|
102
|
+
raise HasOneThroughNestedAssociationsAreReadonly.new(owner, reflection)
|
103
|
+
else
|
104
|
+
raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection)
|
105
|
+
end
|
92
106
|
end
|
93
107
|
end
|
108
|
+
|
109
|
+
def build_record(attributes)
|
110
|
+
inverse = source_reflection.inverse_of
|
111
|
+
target = through_association.target
|
112
|
+
|
113
|
+
if inverse && target && !target.is_a?(Array)
|
114
|
+
attributes[inverse.foreign_key] = target.id
|
115
|
+
end
|
116
|
+
|
117
|
+
super
|
118
|
+
end
|
94
119
|
end
|
95
120
|
end
|
96
121
|
end
|