activerecord 5.0.6 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +638 -2023
- data/MIT-LICENSE +3 -1
- data/README.rdoc +8 -6
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record/aggregations.rb +249 -246
- data/lib/active_record/association_relation.rb +24 -13
- data/lib/active_record/associations/alias_tracker.rb +24 -33
- data/lib/active_record/associations/association.rb +119 -56
- data/lib/active_record/associations/association_scope.rb +94 -94
- data/lib/active_record/associations/belongs_to_association.rb +58 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +18 -25
- data/lib/active_record/associations/builder/belongs_to.rb +43 -54
- data/lib/active_record/associations/builder/collection_association.rb +7 -18
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
- data/lib/active_record/associations/builder/has_many.rb +4 -0
- data/lib/active_record/associations/builder/has_one.rb +37 -1
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +80 -252
- data/lib/active_record/associations/collection_proxy.rb +158 -121
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -29
- data/lib/active_record/associations/has_many_through_association.rb +58 -44
- data/lib/active_record/associations/has_one_association.rb +59 -54
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +134 -176
- data/lib/active_record/associations/preloader/association.rb +84 -125
- data/lib/active_record/associations/preloader/through_association.rb +82 -75
- data/lib/active_record/associations/preloader.rb +90 -102
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +26 -14
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/attribute_assignment.rb +54 -60
- data/lib/active_record/attribute_decorators.rb +38 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +86 -91
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +21 -49
- data/lib/active_record/attribute_methods/serialization.rb +30 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
- data/lib/active_record/attribute_methods/write.rb +35 -33
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attributes.rb +38 -24
- data/lib/active_record/autosave_association.rb +53 -32
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +63 -33
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -11
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
- data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
- data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
- data/lib/active_record/connection_handling.rb +159 -40
- data/lib/active_record/core.rb +202 -162
- data/lib/active_record/counter_cache.rb +57 -28
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +79 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -86
- data/lib/active_record/enum.rb +60 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -3
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +13 -8
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +195 -502
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +151 -97
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +15 -18
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +78 -87
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +48 -29
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +143 -97
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +367 -300
- data/lib/active_record/model_schema.rb +145 -139
- data/lib/active_record/nested_attributes.rb +214 -201
- data/lib/active_record/no_touching.rb +10 -1
- data/lib/active_record/null_relation.rb +13 -34
- data/lib/active_record/persistence.rb +442 -72
- data/lib/active_record/query_cache.rb +15 -14
- data/lib/active_record/querying.rb +36 -23
- data/lib/active_record/railtie.rb +128 -36
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +309 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +211 -249
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/batches.rb +99 -52
- data/lib/active_record/relation/calculations.rb +211 -172
- data/lib/active_record/relation/delegation.rb +67 -65
- data/lib/active_record/relation/finder_methods.rb +208 -247
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +78 -61
- data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +86 -104
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +458 -329
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -7
- data/lib/active_record/relation/where_clause.rb +111 -95
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/relation.rb +429 -318
- data/lib/active_record/result.rb +69 -39
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +83 -99
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +71 -69
- data/lib/active_record/schema_migration.rb +15 -5
- data/lib/active_record/scoping/default.rb +93 -95
- data/lib/active_record/scoping/named.rb +45 -25
- data/lib/active_record/scoping.rb +20 -19
- data/lib/active_record/secure_token.rb +4 -2
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +63 -28
- data/lib/active_record/store.rb +121 -41
- data/lib/active_record/suppressor.rb +4 -1
- data/lib/active_record/table_metadata.rb +26 -20
- data/lib/active_record/tasks/database_tasks.rb +276 -85
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
- data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +70 -35
- data/lib/active_record/touch_later.rb +7 -4
- data/lib/active_record/transactions.rb +133 -149
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +44 -45
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +16 -8
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +2 -1
- data/lib/active_record/type/type_map.rb +13 -15
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +23 -17
- data/lib/active_record/type_caster/connection.rb +17 -12
- data/lib/active_record/type_caster/map.rb +5 -4
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +3 -1
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +29 -42
- data/lib/active_record/validations.rb +7 -4
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -22
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +58 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
- data/lib/rails/generators/active_record/migration.rb +17 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +133 -50
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -20
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set/builder.rb +0 -130
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,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.
|
@@ -42,20 +44,10 @@ 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
|
-
NULL_RELATION = Struct.new(:values, :where_clause, :joins_values).new({}, Relation::WhereClause.empty, [])
|
58
|
-
|
59
51
|
# Eager loads the named associations for the given Active Record record(s).
|
60
52
|
#
|
61
53
|
# In this description, 'association name' shall refer to the name passed
|
@@ -91,14 +83,12 @@ module ActiveRecord
|
|
91
83
|
# { author: :avatar }
|
92
84
|
# [ :books, { author: :avatar } ]
|
93
85
|
def preload(records, associations, preload_scope = nil)
|
94
|
-
records
|
95
|
-
associations = Array.wrap(associations)
|
96
|
-
preload_scope = preload_scope || NULL_RELATION
|
86
|
+
records = Array.wrap(records).compact
|
97
87
|
|
98
88
|
if records.empty?
|
99
89
|
[]
|
100
90
|
else
|
101
|
-
associations.flat_map { |association|
|
91
|
+
Array.wrap(associations).flat_map { |association|
|
102
92
|
preloaders_on association, records, preload_scope
|
103
93
|
}
|
104
94
|
end
|
@@ -106,108 +96,106 @@ module ActiveRecord
|
|
106
96
|
|
107
97
|
private
|
108
98
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
raise ArgumentError, "#{association.inspect} was not recognized for preload"
|
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).uniq
|
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
|
-
# Loads all the given data into +records+ for a singular +association+.
|
136
|
-
#
|
137
|
-
# Functions by instantiating a preloader class such as Preloader::HasManyThrough and
|
138
|
-
# call the +run+ method for each passed in class in the +records+ argument.
|
139
|
-
#
|
140
|
-
# Not all records have the same class, so group then preload group on the reflection
|
141
|
-
# itself so that if various subclass share the same association then we do not split
|
142
|
-
# them unnecessarily
|
143
|
-
#
|
144
|
-
# Additionally, polymorphic belongs_to associations can have multiple associated
|
145
|
-
# classes, depending on the polymorphic_type field. So we group by the classes as
|
146
|
-
# well.
|
147
|
-
def preloaders_for_one(association, records, scope)
|
148
|
-
grouped_records(association, records).flat_map do |reflection, klasses|
|
149
|
-
klasses.map do |rhs_klass, rs|
|
150
|
-
loader = preloader_for(reflection, rs, rhs_klass).new(rhs_klass, rs, reflection, scope)
|
151
|
-
loader.run self
|
152
|
-
loader
|
153
|
-
end
|
154
123
|
end
|
155
|
-
end
|
156
124
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
164
142
|
end
|
165
|
-
h
|
166
|
-
end
|
167
143
|
|
168
|
-
|
169
|
-
|
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
|
170
149
|
|
171
|
-
def
|
172
|
-
|
173
|
-
|
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
|
174
158
|
end
|
175
159
|
|
176
|
-
|
160
|
+
class AlreadyLoaded # :nodoc:
|
161
|
+
def initialize(klass, owners, reflection, preload_scope)
|
162
|
+
@owners = owners
|
163
|
+
@reflection = reflection
|
164
|
+
end
|
177
165
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
end
|
166
|
+
def run
|
167
|
+
self
|
168
|
+
end
|
182
169
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
def self.preloaded_records; []; end
|
187
|
-
def self.owners; []; end
|
188
|
-
end
|
170
|
+
def preloaded_records
|
171
|
+
@preloaded_records ||= records_by_owner.flat_map(&:last)
|
172
|
+
end
|
189
173
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
return NullPreloader unless rhs_klass
|
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
|
196
179
|
|
197
|
-
|
198
|
-
|
180
|
+
private
|
181
|
+
attr_reader :owners, :reflection
|
199
182
|
end
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
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
|
209
198
|
end
|
210
|
-
end
|
211
199
|
end
|
212
200
|
end
|
213
201
|
end
|
@@ -1,16 +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
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
8
|
-
Passing an argument to force an association to reload is now
|
9
|
-
deprecated and will be removed in Rails 5.1. Please call `reload_#{reflection.name}` instead.
|
10
|
-
MSG
|
11
|
-
|
12
|
-
klass.uncached { reload }
|
13
|
-
elsif !loaded? || stale_target?
|
7
|
+
def reader
|
8
|
+
if !loaded? || stale_target?
|
14
9
|
reload
|
15
10
|
end
|
16
11
|
|
@@ -22,17 +17,8 @@ module ActiveRecord
|
|
22
17
|
replace(record)
|
23
18
|
end
|
24
19
|
|
25
|
-
def
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
def create!(attributes = {}, &block)
|
30
|
-
_create_record(attributes, true, &block)
|
31
|
-
end
|
32
|
-
|
33
|
-
def build(attributes = {})
|
34
|
-
record = build_record(attributes)
|
35
|
-
yield(record) if block_given?
|
20
|
+
def build(attributes = {}, &block)
|
21
|
+
record = build_record(attributes, &block)
|
36
22
|
set_new_record(record)
|
37
23
|
record
|
38
24
|
end
|
@@ -40,35 +26,17 @@ module ActiveRecord
|
|
40
26
|
# Implements the reload reader method, e.g. foo.reload_bar for
|
41
27
|
# Foo.has_one :bar
|
42
28
|
def force_reload_reader
|
43
|
-
|
29
|
+
reload(true)
|
44
30
|
target
|
45
31
|
end
|
46
32
|
|
47
33
|
private
|
48
|
-
|
49
|
-
|
50
|
-
scope.scope_for_create.stringify_keys.except(klass.primary_key)
|
51
|
-
end
|
52
|
-
|
53
|
-
def get_records
|
54
|
-
return scope.limit(1).records if skip_statement_cache?
|
55
|
-
|
56
|
-
conn = klass.connection
|
57
|
-
sc = reflection.association_scope_cache(conn, owner) do
|
58
|
-
StatementCache.create(conn) { |params|
|
59
|
-
as = AssociationScope.create { params.bind }
|
60
|
-
target_scope.merge(as.scope(self, conn)).limit(1)
|
61
|
-
}
|
62
|
-
end
|
63
|
-
|
64
|
-
binds = AssociationScope.get_bind_values(owner, reflection.chain)
|
65
|
-
sc.execute binds, klass, klass.connection
|
34
|
+
def scope_for_create
|
35
|
+
super.except!(klass.primary_key)
|
66
36
|
end
|
67
37
|
|
68
38
|
def find_target
|
69
|
-
|
70
|
-
set_inverse_instance record
|
71
|
-
end
|
39
|
+
super.first
|
72
40
|
end
|
73
41
|
|
74
42
|
def replace(record)
|
@@ -79,9 +47,8 @@ module ActiveRecord
|
|
79
47
|
replace(record)
|
80
48
|
end
|
81
49
|
|
82
|
-
def _create_record(attributes, raise_error = false)
|
83
|
-
record = build_record(attributes)
|
84
|
-
yield(record) if block_given?
|
50
|
+
def _create_record(attributes, raise_error = false, &block)
|
51
|
+
record = build_record(attributes, &block)
|
85
52
|
saved = record.save
|
86
53
|
set_new_record(record)
|
87
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
|
#
|
@@ -22,8 +38,6 @@ module ActiveRecord
|
|
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
|
#
|
@@ -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
|
@@ -102,7 +114,7 @@ module ActiveRecord
|
|
102
114
|
attributes[inverse.foreign_key] = target.id
|
103
115
|
end
|
104
116
|
|
105
|
-
super
|
117
|
+
super
|
106
118
|
end
|
107
119
|
end
|
108
120
|
end
|