activerecord 4.2.9 → 6.1.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +964 -1382
- data/MIT-LICENSE +4 -2
- data/README.rdoc +15 -14
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +266 -251
- data/lib/active_record/association_relation.rb +40 -15
- data/lib/active_record/associations/alias_tracker.rb +40 -43
- data/lib/active_record/associations/association.rb +162 -69
- data/lib/active_record/associations/association_scope.rb +105 -130
- data/lib/active_record/associations/belongs_to_association.rb +83 -65
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
- data/lib/active_record/associations/builder/association.rb +57 -43
- data/lib/active_record/associations/builder/belongs_to.rb +74 -57
- data/lib/active_record/associations/builder/collection_association.rb +15 -37
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
- data/lib/active_record/associations/builder/has_many.rb +13 -5
- data/lib/active_record/associations/builder/has_one.rb +44 -6
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +148 -287
- data/lib/active_record/associations/collection_proxy.rb +252 -150
- data/lib/active_record/associations/foreign_association.rb +23 -1
- data/lib/active_record/associations/has_many_association.rb +56 -98
- data/lib/active_record/associations/has_many_through_association.rb +68 -89
- data/lib/active_record/associations/has_one_association.rb +73 -47
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
- 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 +174 -169
- data/lib/active_record/associations/preloader/association.rb +108 -115
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +97 -94
- data/lib/active_record/associations/singular_association.rb +18 -39
- data/lib/active_record/associations/through_association.rb +39 -19
- data/lib/active_record/associations.rb +1845 -1598
- data/lib/active_record/attribute_assignment.rb +59 -185
- data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
- data/lib/active_record/attribute_methods/dirty.rb +168 -148
- data/lib/active_record/attribute_methods/primary_key.rb +93 -83
- data/lib/active_record/attribute_methods/query.rb +8 -10
- data/lib/active_record/attribute_methods/read.rb +19 -79
- data/lib/active_record/attribute_methods/serialization.rb +49 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
- data/lib/active_record/attribute_methods/write.rb +24 -55
- data/lib/active_record/attribute_methods.rb +149 -154
- data/lib/active_record/attributes.rb +234 -78
- data/lib/active_record/autosave_association.rb +133 -60
- data/lib/active_record/base.rb +46 -46
- data/lib/active_record/callbacks.rb +234 -79
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +34 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
- data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
- data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
- data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
- data/lib/active_record/connection_adapters/column.rb +67 -40
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
- data/lib/active_record/connection_adapters/pool_config.rb +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
- 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 +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
- 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 +31 -20
- 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 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
- 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 +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
- data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -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 +170 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
- data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
- data/lib/active_record/connection_adapters.rb +52 -0
- data/lib/active_record/connection_handling.rb +314 -41
- data/lib/active_record/core.rb +458 -241
- data/lib/active_record/counter_cache.rb +70 -49
- 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/database_configurations.rb +272 -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 -106
- data/lib/active_record/enum.rb +211 -92
- data/lib/active_record/errors.rb +224 -54
- data/lib/active_record/explain.rb +27 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +33 -14
- 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 +275 -500
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +175 -110
- data/lib/active_record/insert_all.rb +212 -0
- data/lib/active_record/integration.rb +121 -29
- data/lib/active_record/internal_metadata.rb +62 -0
- data/lib/active_record/legacy_yaml_adapter.rb +27 -5
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +98 -92
- data/lib/active_record/locking/pessimistic.rb +22 -6
- data/lib/active_record/log_subscriber.rb +93 -31
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/migration/command_recorder.rb +185 -90
- data/lib/active_record/migration/compatibility.rb +295 -0
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/migration.rb +673 -325
- data/lib/active_record/model_schema.rb +418 -113
- data/lib/active_record/nested_attributes.rb +263 -224
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -38
- data/lib/active_record/persistence.rb +572 -136
- data/lib/active_record/query_cache.rb +29 -23
- data/lib/active_record/querying.rb +50 -31
- data/lib/active_record/railtie.rb +170 -51
- data/lib/active_record/railties/console_sandbox.rb +3 -3
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +523 -199
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +454 -291
- data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
- data/lib/active_record/relation/batches.rb +217 -59
- data/lib/active_record/relation/calculations.rb +324 -249
- data/lib/active_record/relation/delegation.rb +76 -84
- data/lib/active_record/relation/finder_methods.rb +316 -242
- data/lib/active_record/relation/from_clause.rb +30 -0
- data/lib/active_record/relation/merger.rb +95 -103
- data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -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 +57 -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 +136 -122
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +757 -413
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -20
- data/lib/active_record/relation/where_clause.rb +239 -0
- data/lib/active_record/relation.rb +554 -343
- data/lib/active_record/result.rb +91 -47
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +134 -122
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +141 -92
- data/lib/active_record/schema_migration.rb +24 -23
- data/lib/active_record/scoping/default.rb +96 -83
- data/lib/active_record/scoping/named.rb +78 -36
- data/lib/active_record/scoping.rb +45 -27
- data/lib/active_record/secure_token.rb +48 -0
- data/lib/active_record/serialization.rb +8 -6
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +89 -36
- data/lib/active_record/store.rb +128 -43
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +81 -0
- data/lib/active_record/tasks/database_tasks.rb +364 -130
- data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
- data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
- data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +287 -0
- data/lib/active_record/timestamp.rb +86 -43
- data/lib/active_record/touch_later.rb +65 -0
- data/lib/active_record/transactions.rb +182 -163
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +126 -0
- data/lib/active_record/type/date.rb +4 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- 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 +27 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +21 -16
- data/lib/active_record/type/type_map.rb +16 -19
- data/lib/active_record/type/unsigned_integer.rb +9 -8
- data/lib/active_record/type.rb +84 -23
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -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 +12 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +63 -56
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +42 -29
- 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/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 +76 -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/nodes.rb +70 -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/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/visitors.rb +13 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +54 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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 +43 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
- data/lib/rails/generators/active_record/migration.rb +35 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +172 -65
- 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 -163
- data/lib/active_record/attribute_decorators.rb +0 -66
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
- 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/integer.rb +0 -11
- 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 -31
- data/lib/active_record/type/decimal.rb +0 -64
- 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 -59
- 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 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/enumerable"
|
4
|
+
|
1
5
|
module ActiveRecord
|
2
6
|
module Associations
|
3
7
|
# Implements the details of eager loading of Active Record associations.
|
@@ -42,16 +46,8 @@ module ActiveRecord
|
|
42
46
|
extend ActiveSupport::Autoload
|
43
47
|
|
44
48
|
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'
|
49
|
+
autoload :Association, "active_record/associations/preloader/association"
|
50
|
+
autoload :ThroughAssociation, "active_record/associations/preloader/through_association"
|
55
51
|
end
|
56
52
|
|
57
53
|
# Eager loads the named associations for the given Active Record record(s).
|
@@ -64,7 +60,7 @@ module ActiveRecord
|
|
64
60
|
# == Parameters
|
65
61
|
# +records+ is an array of ActiveRecord::Base. This array needs not be flat,
|
66
62
|
# i.e. +records+ itself may also contain arrays of records. In any case,
|
67
|
-
# +preload_associations+ will preload
|
63
|
+
# +preload_associations+ will preload all associations records by
|
68
64
|
# flattening +records+.
|
69
65
|
#
|
70
66
|
# +associations+ specifies one or more associations that you want to
|
@@ -88,116 +84,123 @@ module ActiveRecord
|
|
88
84
|
# [ :books, :author ]
|
89
85
|
# { author: :avatar }
|
90
86
|
# [ :books, { author: :avatar } ]
|
91
|
-
|
92
|
-
NULL_RELATION = Struct.new(:values, :bind_values).new({}, [])
|
93
|
-
|
94
87
|
def preload(records, associations, preload_scope = nil)
|
95
|
-
records
|
96
|
-
associations = Array.wrap(associations)
|
97
|
-
preload_scope = preload_scope || NULL_RELATION
|
88
|
+
records = Array.wrap(records).compact
|
98
89
|
|
99
90
|
if records.empty?
|
100
91
|
[]
|
101
92
|
else
|
102
|
-
associations.flat_map { |association|
|
93
|
+
Array.wrap(associations).flat_map { |association|
|
103
94
|
preloaders_on association, records, preload_scope
|
104
95
|
}
|
105
96
|
end
|
106
97
|
end
|
107
98
|
|
108
|
-
|
109
|
-
|
110
|
-
def preloaders_on(association, records, scope)
|
111
|
-
case association
|
112
|
-
when Hash
|
113
|
-
preloaders_for_hash(association, records, scope)
|
114
|
-
when Symbol
|
115
|
-
preloaders_for_one(association, records, scope)
|
116
|
-
when String
|
117
|
-
preloaders_for_one(association.to_sym, records, scope)
|
118
|
-
else
|
119
|
-
raise ArgumentError, "#{association.inspect} was not recognised for preload"
|
120
|
-
end
|
99
|
+
def initialize(associate_by_default: true)
|
100
|
+
@associate_by_default = associate_by_default
|
121
101
|
end
|
122
102
|
|
123
|
-
|
124
|
-
|
125
|
-
|
103
|
+
private
|
104
|
+
# Loads all the given data into +records+ for the +association+.
|
105
|
+
def preloaders_on(association, records, scope, polymorphic_parent = false)
|
106
|
+
case association
|
107
|
+
when Hash
|
108
|
+
preloaders_for_hash(association, records, scope, polymorphic_parent)
|
109
|
+
when Symbol, String
|
110
|
+
preloaders_for_one(association, records, scope, polymorphic_parent)
|
111
|
+
else
|
112
|
+
raise ArgumentError, "#{association.inspect} was not recognized for preload"
|
113
|
+
end
|
114
|
+
end
|
126
115
|
|
127
|
-
|
128
|
-
|
129
|
-
|
116
|
+
def preloaders_for_hash(association, records, scope, polymorphic_parent)
|
117
|
+
association.flat_map { |parent, child|
|
118
|
+
grouped_records(parent, records, polymorphic_parent).flat_map do |reflection, reflection_records|
|
119
|
+
loaders = preloaders_for_reflection(reflection, reflection_records, scope)
|
120
|
+
recs = loaders.flat_map(&:preloaded_records).uniq
|
121
|
+
child_polymorphic_parent = reflection && reflection.options[:polymorphic]
|
122
|
+
loaders.concat Array.wrap(child).flat_map { |assoc|
|
123
|
+
preloaders_on assoc, recs, scope, child_polymorphic_parent
|
124
|
+
}
|
125
|
+
loaders
|
126
|
+
end
|
130
127
|
}
|
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
128
|
end
|
150
|
-
end
|
151
129
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
130
|
+
# Loads all the given data into +records+ for a singular +association+.
|
131
|
+
#
|
132
|
+
# Functions by instantiating a preloader class such as Preloader::Association and
|
133
|
+
# call the +run+ method for each passed in class in the +records+ argument.
|
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, polymorphic_parent)
|
143
|
+
grouped_records(association, records, polymorphic_parent)
|
144
|
+
.flat_map do |reflection, reflection_records|
|
145
|
+
preloaders_for_reflection reflection, reflection_records, scope
|
146
|
+
end
|
159
147
|
end
|
160
|
-
h
|
161
|
-
end
|
162
148
|
|
163
|
-
|
164
|
-
|
149
|
+
def preloaders_for_reflection(reflection, records, scope)
|
150
|
+
records.group_by { |record| record.association(reflection.name).klass }.map do |rhs_klass, rs|
|
151
|
+
preloader_for(reflection, rs).new(rhs_klass, rs, reflection, scope, @associate_by_default).run
|
152
|
+
end
|
153
|
+
end
|
165
154
|
|
166
|
-
def
|
167
|
-
|
168
|
-
|
155
|
+
def grouped_records(association, records, polymorphic_parent)
|
156
|
+
h = {}
|
157
|
+
records.each do |record|
|
158
|
+
reflection = record.class._reflect_on_association(association)
|
159
|
+
next if polymorphic_parent && !reflection || !record.association(association).klass
|
160
|
+
(h[reflection] ||= []) << record
|
161
|
+
end
|
162
|
+
h
|
169
163
|
end
|
170
164
|
|
171
|
-
|
165
|
+
class AlreadyLoaded # :nodoc:
|
166
|
+
def initialize(klass, owners, reflection, preload_scope, associate_by_default = true)
|
167
|
+
@owners = owners
|
168
|
+
@reflection = reflection
|
169
|
+
end
|
172
170
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
end
|
171
|
+
def run
|
172
|
+
self
|
173
|
+
end
|
177
174
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
def self.preloaded_records; []; end
|
182
|
-
end
|
175
|
+
def preloaded_records
|
176
|
+
@preloaded_records ||= records_by_owner.flat_map(&:last)
|
177
|
+
end
|
183
178
|
|
184
|
-
|
185
|
-
|
179
|
+
def records_by_owner
|
180
|
+
@records_by_owner ||= owners.index_with do |owner|
|
181
|
+
Array(owner.association(reflection.name).target)
|
182
|
+
end
|
183
|
+
end
|
186
184
|
|
187
|
-
|
188
|
-
|
185
|
+
private
|
186
|
+
attr_reader :owners, :reflection
|
189
187
|
end
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
188
|
+
|
189
|
+
# Returns a class containing the logic needed to load preload the data
|
190
|
+
# and attach it to a relation. The class returned implements a `run` method
|
191
|
+
# that accepts a preloader.
|
192
|
+
def preloader_for(reflection, owners)
|
193
|
+
if owners.all? { |o| o.association(reflection.name).loaded? }
|
194
|
+
return AlreadyLoaded
|
195
|
+
end
|
196
|
+
reflection.check_preloadable!
|
197
|
+
|
198
|
+
if reflection.options[:through]
|
199
|
+
ThroughAssociation
|
200
|
+
else
|
201
|
+
Association
|
202
|
+
end
|
199
203
|
end
|
200
|
-
end
|
201
204
|
end
|
202
205
|
end
|
203
206
|
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,46 +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 = nil, &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
|
-
return scope.limit(1).to_a if skip_statement_cache?
|
43
|
-
|
44
|
-
conn = klass.connection
|
45
|
-
sc = reflection.association_scope_cache(conn, owner) do
|
46
|
-
StatementCache.create(conn) { |params|
|
47
|
-
as = AssociationScope.create { params.bind }
|
48
|
-
target_scope.merge(as.scope(self, conn)).limit(1)
|
49
|
-
}
|
50
|
-
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
|
51
32
|
|
52
|
-
|
53
|
-
|
33
|
+
private
|
34
|
+
def scope_for_create
|
35
|
+
super.except!(klass.primary_key)
|
54
36
|
end
|
55
37
|
|
56
38
|
def find_target
|
57
|
-
|
58
|
-
set_inverse_instance record
|
59
|
-
end
|
39
|
+
super.first
|
60
40
|
end
|
61
41
|
|
62
42
|
def replace(record)
|
@@ -67,9 +47,8 @@ module ActiveRecord
|
|
67
47
|
replace(record)
|
68
48
|
end
|
69
49
|
|
70
|
-
def _create_record(attributes, raise_error = false)
|
71
|
-
record = build_record(attributes)
|
72
|
-
yield(record) if block_given?
|
50
|
+
def _create_record(attributes, raise_error = false, &block)
|
51
|
+
record = build_record(attributes, &block)
|
73
52
|
saved = record.save
|
74
53
|
set_new_record(record)
|
75
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
|
17
|
+
|
18
|
+
refl
|
19
|
+
end
|
20
|
+
end
|
7
21
|
|
8
|
-
|
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,20 +30,18 @@ module ActiveRecord
|
|
14
30
|
def target_scope
|
15
31
|
scope = super
|
16
32
|
reflection.chain.drop(1).each do |reflection|
|
17
|
-
relation = reflection.klass.
|
33
|
+
relation = reflection.klass.scope_for_association
|
18
34
|
scope.merge!(
|
19
|
-
relation.except(:select, :create_with, :includes, :preload, :joins, :
|
35
|
+
relation.except(:select, :create_with, :includes, :preload, :eager_load, :joins, :left_outer_joins)
|
20
36
|
)
|
21
37
|
end
|
22
38
|
scope
|
23
39
|
end
|
24
40
|
|
25
|
-
private
|
26
|
-
|
27
41
|
# Construct attributes for :through pointing to owner and associate. This is used by the
|
28
42
|
# methods which create and delete records on the association.
|
29
43
|
#
|
30
|
-
# We only support indirectly modifying through associations which
|
44
|
+
# We only support indirectly modifying through associations which have a belongs_to source.
|
31
45
|
# This is the "has_many :tags, through: :taggings" situation, where the join model
|
32
46
|
# typically has a belongs_to on both side. In other words, associations which could also
|
33
47
|
# be represented as has_and_belongs_to_many associations.
|
@@ -39,24 +53,22 @@ module ActiveRecord
|
|
39
53
|
def construct_join_attributes(*records)
|
40
54
|
ensure_mutable
|
41
55
|
|
42
|
-
|
56
|
+
association_primary_key = source_reflection.association_primary_key(reflection.klass)
|
57
|
+
|
58
|
+
if association_primary_key == reflection.klass.primary_key && !options[:source_type]
|
43
59
|
join_attributes = { source_reflection.name => records }
|
44
60
|
else
|
45
61
|
join_attributes = {
|
46
|
-
source_reflection.foreign_key =>
|
47
|
-
records.map { |record|
|
48
|
-
record.send(source_reflection.association_primary_key(reflection.klass))
|
49
|
-
}
|
62
|
+
source_reflection.foreign_key => records.map(&association_primary_key.to_sym)
|
50
63
|
}
|
51
64
|
end
|
52
65
|
|
53
66
|
if options[:source_type]
|
54
|
-
join_attributes[source_reflection.foreign_type] =
|
55
|
-
records.map { |record| record.class.base_class.name }
|
67
|
+
join_attributes[source_reflection.foreign_type] = [ options[:source_type] ]
|
56
68
|
end
|
57
69
|
|
58
70
|
if records.count == 1
|
59
|
-
|
71
|
+
join_attributes.transform_values!(&:first)
|
60
72
|
else
|
61
73
|
join_attributes
|
62
74
|
end
|
@@ -76,13 +88,21 @@ module ActiveRecord
|
|
76
88
|
|
77
89
|
def ensure_mutable
|
78
90
|
unless source_reflection.belongs_to?
|
79
|
-
|
91
|
+
if reflection.has_one?
|
92
|
+
raise HasOneThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
|
93
|
+
else
|
94
|
+
raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
|
95
|
+
end
|
80
96
|
end
|
81
97
|
end
|
82
98
|
|
83
99
|
def ensure_not_nested
|
84
100
|
if reflection.nested?
|
85
|
-
|
101
|
+
if reflection.has_one?
|
102
|
+
raise HasOneThroughNestedAssociationsAreReadonly.new(owner, reflection)
|
103
|
+
else
|
104
|
+
raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection)
|
105
|
+
end
|
86
106
|
end
|
87
107
|
end
|
88
108
|
|
@@ -94,7 +114,7 @@ module ActiveRecord
|
|
94
114
|
attributes[inverse.foreign_key] = target.id
|
95
115
|
end
|
96
116
|
|
97
|
-
super
|
117
|
+
super
|
98
118
|
end
|
99
119
|
end
|
100
120
|
end
|