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,10 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Associations
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# object, known as the <tt>@target</tt>. The kind of association any proxy is
|
6
|
-
# about is available in <tt>@reflection</tt>. That's an instance of the class
|
7
|
-
# ActiveRecord::Reflection::AssociationReflection.
|
5
|
+
# Collection proxies in Active Record are middlemen between an
|
6
|
+
# <tt>association</tt>, and its <tt>target</tt> result set.
|
8
7
|
#
|
9
8
|
# For example, given
|
10
9
|
#
|
@@ -14,26 +13,26 @@ module ActiveRecord
|
|
14
13
|
#
|
15
14
|
# blog = Blog.first
|
16
15
|
#
|
17
|
-
#
|
18
|
-
# <tt
|
19
|
-
#
|
16
|
+
# The collection proxy returned by <tt>blog.posts</tt> is built from a
|
17
|
+
# <tt>:has_many</tt> <tt>association</tt>, and delegates to a collection
|
18
|
+
# of posts as the <tt>target</tt>.
|
20
19
|
#
|
21
|
-
# This class delegates unknown methods to <tt
|
22
|
-
#
|
20
|
+
# This class delegates unknown methods to the <tt>association</tt>'s
|
21
|
+
# relation class via a delegate cache.
|
23
22
|
#
|
24
|
-
# The <tt
|
23
|
+
# The <tt>target</tt> result set is not loaded until needed. For example,
|
25
24
|
#
|
26
25
|
# blog.posts.count
|
27
26
|
#
|
28
27
|
# is computed directly through SQL and does not trigger by itself the
|
29
28
|
# instantiation of the actual post records.
|
30
29
|
class CollectionProxy < Relation
|
31
|
-
delegate(*(ActiveRecord::Calculations.public_instance_methods - [:count]), to: :scope)
|
32
|
-
|
33
30
|
def initialize(klass, association) #:nodoc:
|
34
31
|
@association = association
|
35
|
-
super klass
|
36
|
-
|
32
|
+
super klass
|
33
|
+
|
34
|
+
extensions = association.extensions
|
35
|
+
extend(*extensions) if extensions.any?
|
37
36
|
end
|
38
37
|
|
39
38
|
def target
|
@@ -53,6 +52,12 @@ module ActiveRecord
|
|
53
52
|
@association.loaded?
|
54
53
|
end
|
55
54
|
|
55
|
+
##
|
56
|
+
# :method: select
|
57
|
+
#
|
58
|
+
# :call-seq:
|
59
|
+
# select(*fields, &block)
|
60
|
+
#
|
56
61
|
# Works in two ways.
|
57
62
|
#
|
58
63
|
# *First:* Specify a subset of fields to be selected from the result set.
|
@@ -75,7 +80,7 @@ module ActiveRecord
|
|
75
80
|
# # #<Pet id: nil, name: "Choo-Choo">
|
76
81
|
# # ]
|
77
82
|
#
|
78
|
-
# person.pets.select(:id, :name
|
83
|
+
# person.pets.select(:id, :name)
|
79
84
|
# # => [
|
80
85
|
# # #<Pet id: 1, name: "Fancy-Fancy">,
|
81
86
|
# # #<Pet id: 2, name: "Spook">,
|
@@ -100,18 +105,9 @@ module ActiveRecord
|
|
100
105
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
101
106
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
102
107
|
# # ]
|
103
|
-
#
|
104
|
-
# person.pets.select(:name) { |pet| pet.name =~ /oo/ }
|
105
|
-
# # => [
|
106
|
-
# # #<Pet id: 2, name: "Spook">,
|
107
|
-
# # #<Pet id: 3, name: "Choo-Choo">
|
108
|
-
# # ]
|
109
|
-
def select(*fields, &block)
|
110
|
-
@association.select(*fields, &block)
|
111
|
-
end
|
112
108
|
|
113
109
|
# Finds an object in the collection responding to the +id+. Uses the same
|
114
|
-
# rules as
|
110
|
+
# rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound
|
115
111
|
# error if the object cannot be found.
|
116
112
|
#
|
117
113
|
# class Person < ActiveRecord::Base
|
@@ -126,7 +122,7 @@ module ActiveRecord
|
|
126
122
|
# # ]
|
127
123
|
#
|
128
124
|
# person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
|
129
|
-
# person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=4
|
125
|
+
# person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
|
130
126
|
#
|
131
127
|
# person.pets.find(2) { |pet| pet.name.downcase! }
|
132
128
|
# # => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
|
@@ -136,10 +132,17 @@ module ActiveRecord
|
|
136
132
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
137
133
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
138
134
|
# # ]
|
139
|
-
def find(*args
|
140
|
-
|
135
|
+
def find(*args)
|
136
|
+
return super if block_given?
|
137
|
+
@association.find(*args)
|
141
138
|
end
|
142
139
|
|
140
|
+
##
|
141
|
+
# :method: first
|
142
|
+
#
|
143
|
+
# :call-seq:
|
144
|
+
# first(limit = nil)
|
145
|
+
#
|
143
146
|
# Returns the first record, or the first +n+ records, from the collection.
|
144
147
|
# If the collection is empty, the first form returns +nil+, and the second
|
145
148
|
# form returns an empty array.
|
@@ -166,35 +169,63 @@ module ActiveRecord
|
|
166
169
|
# another_person_without.pets # => []
|
167
170
|
# another_person_without.pets.first # => nil
|
168
171
|
# another_person_without.pets.first(3) # => []
|
169
|
-
def first(*args)
|
170
|
-
@association.first(*args)
|
171
|
-
end
|
172
172
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
173
|
+
##
|
174
|
+
# :method: second
|
175
|
+
#
|
176
|
+
# :call-seq:
|
177
|
+
# second()
|
178
|
+
#
|
179
|
+
# Same as #first except returns only the second record.
|
177
180
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
181
|
+
##
|
182
|
+
# :method: third
|
183
|
+
#
|
184
|
+
# :call-seq:
|
185
|
+
# third()
|
186
|
+
#
|
187
|
+
# Same as #first except returns only the third record.
|
182
188
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
189
|
+
##
|
190
|
+
# :method: fourth
|
191
|
+
#
|
192
|
+
# :call-seq:
|
193
|
+
# fourth()
|
194
|
+
#
|
195
|
+
# Same as #first except returns only the fourth record.
|
187
196
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
197
|
+
##
|
198
|
+
# :method: fifth
|
199
|
+
#
|
200
|
+
# :call-seq:
|
201
|
+
# fifth()
|
202
|
+
#
|
203
|
+
# Same as #first except returns only the fifth record.
|
192
204
|
|
193
|
-
|
205
|
+
##
|
206
|
+
# :method: forty_two
|
207
|
+
#
|
208
|
+
# :call-seq:
|
209
|
+
# forty_two()
|
210
|
+
#
|
211
|
+
# Same as #first except returns only the forty second record.
|
194
212
|
# Also known as accessing "the reddit".
|
195
|
-
|
196
|
-
|
197
|
-
|
213
|
+
|
214
|
+
##
|
215
|
+
# :method: third_to_last
|
216
|
+
#
|
217
|
+
# :call-seq:
|
218
|
+
# third_to_last()
|
219
|
+
#
|
220
|
+
# Same as #first except returns only the third-to-last record.
|
221
|
+
|
222
|
+
##
|
223
|
+
# :method: second_to_last
|
224
|
+
#
|
225
|
+
# :call-seq:
|
226
|
+
# second_to_last()
|
227
|
+
#
|
228
|
+
# Same as #first except returns only the second-to-last record.
|
198
229
|
|
199
230
|
# Returns the last record, or the last +n+ records, from the collection.
|
200
231
|
# If the collection is empty, the first form returns +nil+, and the second
|
@@ -222,8 +253,39 @@ module ActiveRecord
|
|
222
253
|
# another_person_without.pets # => []
|
223
254
|
# another_person_without.pets.last # => nil
|
224
255
|
# another_person_without.pets.last(3) # => []
|
225
|
-
def last(
|
226
|
-
|
256
|
+
def last(limit = nil)
|
257
|
+
load_target if find_from_target?
|
258
|
+
super
|
259
|
+
end
|
260
|
+
|
261
|
+
# Gives a record (or N records if a parameter is supplied) from the collection
|
262
|
+
# using the same rules as <tt>ActiveRecord::Base.take</tt>.
|
263
|
+
#
|
264
|
+
# class Person < ActiveRecord::Base
|
265
|
+
# has_many :pets
|
266
|
+
# end
|
267
|
+
#
|
268
|
+
# person.pets
|
269
|
+
# # => [
|
270
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
271
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
272
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
273
|
+
# # ]
|
274
|
+
#
|
275
|
+
# person.pets.take # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
|
276
|
+
#
|
277
|
+
# person.pets.take(2)
|
278
|
+
# # => [
|
279
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
280
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>
|
281
|
+
# # ]
|
282
|
+
#
|
283
|
+
# another_person_without.pets # => []
|
284
|
+
# another_person_without.pets.take # => nil
|
285
|
+
# another_person_without.pets.take(2) # => []
|
286
|
+
def take(limit = nil)
|
287
|
+
load_target if find_from_target?
|
288
|
+
super
|
227
289
|
end
|
228
290
|
|
229
291
|
# Returns a new object of the collection type that has been instantiated
|
@@ -285,7 +347,7 @@ module ActiveRecord
|
|
285
347
|
@association.create(attributes, &block)
|
286
348
|
end
|
287
349
|
|
288
|
-
# Like
|
350
|
+
# Like #create, except that if the record is invalid, raises an exception.
|
289
351
|
#
|
290
352
|
# class Person
|
291
353
|
# has_many :pets
|
@@ -301,34 +363,6 @@ module ActiveRecord
|
|
301
363
|
@association.create!(attributes, &block)
|
302
364
|
end
|
303
365
|
|
304
|
-
# Add one or more records to the collection by setting their foreign keys
|
305
|
-
# to the association's primary key. Since << flattens its argument list and
|
306
|
-
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
|
307
|
-
# so method calls may be chained.
|
308
|
-
#
|
309
|
-
# class Person < ActiveRecord::Base
|
310
|
-
# has_many :pets
|
311
|
-
# end
|
312
|
-
#
|
313
|
-
# person.pets.size # => 0
|
314
|
-
# person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
|
315
|
-
# person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo'))
|
316
|
-
# person.pets.size # => 3
|
317
|
-
#
|
318
|
-
# person.id # => 1
|
319
|
-
# person.pets
|
320
|
-
# # => [
|
321
|
-
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
322
|
-
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
323
|
-
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
324
|
-
# # ]
|
325
|
-
#
|
326
|
-
# person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
|
327
|
-
# person.pets.size # => 5
|
328
|
-
def concat(*records)
|
329
|
-
@association.concat(*records)
|
330
|
-
end
|
331
|
-
|
332
366
|
# Replaces this collection with +other_array+. This will perform a diff
|
333
367
|
# and delete/add only records that have changed.
|
334
368
|
#
|
@@ -359,7 +393,7 @@ module ActiveRecord
|
|
359
393
|
# specified by the +:dependent+ option. If no +:dependent+ option is given,
|
360
394
|
# then it will follow the default strategy.
|
361
395
|
#
|
362
|
-
# For
|
396
|
+
# For <tt>has_many :through</tt> associations, the default deletion strategy is
|
363
397
|
# +:delete_all+.
|
364
398
|
#
|
365
399
|
# For +has_many+ associations, the default deletion strategy is +:nullify+.
|
@@ -394,7 +428,7 @@ module ActiveRecord
|
|
394
428
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: nil>
|
395
429
|
# # ]
|
396
430
|
#
|
397
|
-
# Both +has_many+ and
|
431
|
+
# Both +has_many+ and <tt>has_many :through</tt> dependencies default to the
|
398
432
|
# +:delete_all+ strategy if the +:dependent+ option is set to +:destroy+.
|
399
433
|
# Records are not instantiated and callbacks will not be fired.
|
400
434
|
#
|
@@ -413,7 +447,7 @@ module ActiveRecord
|
|
413
447
|
# person.pets.delete_all
|
414
448
|
#
|
415
449
|
# Pet.find(1, 2, 3)
|
416
|
-
# # => ActiveRecord::RecordNotFound
|
450
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
|
417
451
|
#
|
418
452
|
# If it is set to <tt>:delete_all</tt>, all the objects are deleted
|
419
453
|
# *without* calling their +destroy+ method.
|
@@ -433,9 +467,9 @@ module ActiveRecord
|
|
433
467
|
# person.pets.delete_all
|
434
468
|
#
|
435
469
|
# Pet.find(1, 2, 3)
|
436
|
-
# # => ActiveRecord::RecordNotFound
|
470
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
|
437
471
|
def delete_all(dependent = nil)
|
438
|
-
@association.delete_all(dependent)
|
472
|
+
@association.delete_all(dependent).tap { reset_scope }
|
439
473
|
end
|
440
474
|
|
441
475
|
# Deletes the records of the collection directly from the database
|
@@ -462,18 +496,19 @@ module ActiveRecord
|
|
462
496
|
#
|
463
497
|
# Pet.find(1) # => Couldn't find Pet with id=1
|
464
498
|
def destroy_all
|
465
|
-
@association.destroy_all
|
499
|
+
@association.destroy_all.tap { reset_scope }
|
466
500
|
end
|
467
501
|
|
468
|
-
# Deletes the +records+ supplied
|
469
|
-
#
|
470
|
-
#
|
502
|
+
# Deletes the +records+ supplied from the collection according to the strategy
|
503
|
+
# specified by the +:dependent+ option. If no +:dependent+ option is given,
|
504
|
+
# then it will follow the default strategy. Returns an array with the
|
471
505
|
# deleted records.
|
472
506
|
#
|
473
|
-
#
|
474
|
-
#
|
475
|
-
#
|
476
|
-
# strategy is
|
507
|
+
# For <tt>has_many :through</tt> associations, the default deletion strategy is
|
508
|
+
# +:delete_all+.
|
509
|
+
#
|
510
|
+
# For +has_many+ associations, the default deletion strategy is +:nullify+.
|
511
|
+
# This sets the foreign keys to +NULL+.
|
477
512
|
#
|
478
513
|
# class Person < ActiveRecord::Base
|
479
514
|
# has_many :pets # dependent: :nullify option by default
|
@@ -526,7 +561,7 @@ module ActiveRecord
|
|
526
561
|
# # => [#<Pet id: 2, name: "Spook", person_id: 1>]
|
527
562
|
#
|
528
563
|
# Pet.find(1, 3)
|
529
|
-
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with
|
564
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
|
530
565
|
#
|
531
566
|
# If it is set to <tt>:delete_all</tt>, all the +records+ are deleted
|
532
567
|
# *without* calling their +destroy+ method.
|
@@ -554,9 +589,9 @@ module ActiveRecord
|
|
554
589
|
# # ]
|
555
590
|
#
|
556
591
|
# Pet.find(1)
|
557
|
-
# # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=1
|
592
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
|
558
593
|
#
|
559
|
-
# You can pass +
|
594
|
+
# You can pass +Integer+ or +String+ values, it finds the records
|
560
595
|
# responding to the +id+ and executes delete on them.
|
561
596
|
#
|
562
597
|
# class Person < ActiveRecord::Base
|
@@ -580,7 +615,7 @@ module ActiveRecord
|
|
580
615
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
581
616
|
# # ]
|
582
617
|
def delete(*records)
|
583
|
-
@association.delete(*records)
|
618
|
+
@association.delete(*records).tap { reset_scope }
|
584
619
|
end
|
585
620
|
|
586
621
|
# Destroys the +records+ supplied and removes them from the collection.
|
@@ -618,9 +653,9 @@ module ActiveRecord
|
|
618
653
|
# person.pets.size # => 0
|
619
654
|
# person.pets # => []
|
620
655
|
#
|
621
|
-
# Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with
|
656
|
+
# Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
|
622
657
|
#
|
623
|
-
# You can pass +
|
658
|
+
# You can pass +Integer+ or +String+ values, it finds the records
|
624
659
|
# responding to the +id+ and then deletes them from the database.
|
625
660
|
#
|
626
661
|
# person.pets.size # => 3
|
@@ -650,11 +685,17 @@ module ActiveRecord
|
|
650
685
|
# person.pets.size # => 0
|
651
686
|
# person.pets # => []
|
652
687
|
#
|
653
|
-
# Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with
|
688
|
+
# Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
|
654
689
|
def destroy(*records)
|
655
|
-
@association.destroy(*records)
|
690
|
+
@association.destroy(*records).tap { reset_scope }
|
656
691
|
end
|
657
692
|
|
693
|
+
##
|
694
|
+
# :method: distinct
|
695
|
+
#
|
696
|
+
# :call-seq:
|
697
|
+
# distinct(value = true)
|
698
|
+
#
|
658
699
|
# Specifies whether the records should be unique or not.
|
659
700
|
#
|
660
701
|
# class Person < ActiveRecord::Base
|
@@ -669,17 +710,35 @@ module ActiveRecord
|
|
669
710
|
#
|
670
711
|
# person.pets.select(:name).distinct
|
671
712
|
# # => [#<Pet name: "Fancy-Fancy">]
|
672
|
-
|
673
|
-
|
713
|
+
#
|
714
|
+
# person.pets.select(:name).distinct.distinct(false)
|
715
|
+
# # => [
|
716
|
+
# # #<Pet name: "Fancy-Fancy">,
|
717
|
+
# # #<Pet name: "Fancy-Fancy">
|
718
|
+
# # ]
|
719
|
+
|
720
|
+
#--
|
721
|
+
def calculate(operation, column_name)
|
722
|
+
null_scope? ? scope.calculate(operation, column_name) : super
|
674
723
|
end
|
675
|
-
alias uniq distinct
|
676
724
|
|
677
|
-
|
725
|
+
def pluck(*column_names)
|
726
|
+
null_scope? ? scope.pluck(*column_names) : super
|
727
|
+
end
|
728
|
+
|
729
|
+
##
|
730
|
+
# :method: count
|
731
|
+
#
|
732
|
+
# :call-seq:
|
733
|
+
# count(column_name = nil, &block)
|
734
|
+
#
|
735
|
+
# Count all records.
|
678
736
|
#
|
679
737
|
# class Person < ActiveRecord::Base
|
680
738
|
# has_many :pets
|
681
739
|
# end
|
682
740
|
#
|
741
|
+
# # This will perform the count using SQL.
|
683
742
|
# person.pets.count # => 3
|
684
743
|
# person.pets
|
685
744
|
# # => [
|
@@ -687,11 +746,11 @@ module ActiveRecord
|
|
687
746
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
688
747
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
689
748
|
# # ]
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
749
|
+
#
|
750
|
+
# Passing a block will select all of a person's pets in SQL and then
|
751
|
+
# perform the count using Ruby.
|
752
|
+
#
|
753
|
+
# person.pets.count { |pet| pet.name.include?('-') } # => 2
|
695
754
|
|
696
755
|
# Returns the size of the collection. If the collection hasn't been loaded,
|
697
756
|
# it executes a <tt>SELECT COUNT(*)</tt> query. Else it calls <tt>collection.size</tt>.
|
@@ -721,6 +780,12 @@ module ActiveRecord
|
|
721
780
|
@association.size
|
722
781
|
end
|
723
782
|
|
783
|
+
##
|
784
|
+
# :method: length
|
785
|
+
#
|
786
|
+
# :call-seq:
|
787
|
+
# length()
|
788
|
+
#
|
724
789
|
# Returns the size of the collection calling +size+ on the target.
|
725
790
|
# If the collection has been already loaded, +length+ and +size+ are
|
726
791
|
# equivalent. If not and you are going to need the records anyway this
|
@@ -741,14 +806,11 @@ module ActiveRecord
|
|
741
806
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
742
807
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
743
808
|
# # ]
|
744
|
-
def length
|
745
|
-
@association.length
|
746
|
-
end
|
747
809
|
|
748
810
|
# Returns +true+ if the collection is empty. If the collection has been
|
749
811
|
# loaded it is equivalent
|
750
812
|
# to <tt>collection.size.zero?</tt>. If the collection has not been loaded,
|
751
|
-
# it is equivalent to <tt
|
813
|
+
# it is equivalent to <tt>!collection.exists?</tt>. If the collection has
|
752
814
|
# not already been loaded and you are going to fetch the records anyway it
|
753
815
|
# is better to check <tt>collection.length.zero?</tt>.
|
754
816
|
#
|
@@ -767,6 +829,12 @@ module ActiveRecord
|
|
767
829
|
@association.empty?
|
768
830
|
end
|
769
831
|
|
832
|
+
##
|
833
|
+
# :method: any?
|
834
|
+
#
|
835
|
+
# :call-seq:
|
836
|
+
# any?()
|
837
|
+
#
|
770
838
|
# Returns +true+ if the collection is not empty.
|
771
839
|
#
|
772
840
|
# class Person < ActiveRecord::Base
|
@@ -777,7 +845,7 @@ module ActiveRecord
|
|
777
845
|
# person.pets.any? # => false
|
778
846
|
#
|
779
847
|
# person.pets << Pet.new(name: 'Snoop')
|
780
|
-
# person.pets.count # =>
|
848
|
+
# person.pets.count # => 1
|
781
849
|
# person.pets.any? # => true
|
782
850
|
#
|
783
851
|
# You can also pass a +block+ to define criteria. The behavior
|
@@ -796,10 +864,13 @@ module ActiveRecord
|
|
796
864
|
# pet.group == 'dogs'
|
797
865
|
# end
|
798
866
|
# # => true
|
799
|
-
def any?(&block)
|
800
|
-
@association.any?(&block)
|
801
|
-
end
|
802
867
|
|
868
|
+
##
|
869
|
+
# :method: many?
|
870
|
+
#
|
871
|
+
# :call-seq:
|
872
|
+
# many?()
|
873
|
+
#
|
803
874
|
# Returns true if the collection has more than one record.
|
804
875
|
# Equivalent to <tt>collection.size > 1</tt>.
|
805
876
|
#
|
@@ -834,9 +905,6 @@ module ActiveRecord
|
|
834
905
|
# pet.group == 'cats'
|
835
906
|
# end
|
836
907
|
# # => true
|
837
|
-
def many?(&block)
|
838
|
-
@association.many?(&block)
|
839
|
-
end
|
840
908
|
|
841
909
|
# Returns +true+ if the given +record+ is present in the collection.
|
842
910
|
#
|
@@ -852,27 +920,14 @@ module ActiveRecord
|
|
852
920
|
!!@association.include?(record)
|
853
921
|
end
|
854
922
|
|
855
|
-
def arel
|
856
|
-
scope.arel
|
857
|
-
end
|
858
|
-
|
859
923
|
def proxy_association
|
860
924
|
@association
|
861
925
|
end
|
862
926
|
|
863
|
-
# We don't want this object to be put on the scoping stack, because
|
864
|
-
# that could create an infinite loop where we call an @association
|
865
|
-
# method, which gets the current scope, which is this object, which
|
866
|
-
# delegates to @association, and so on.
|
867
|
-
def scoping
|
868
|
-
@association.scope.scoping { yield }
|
869
|
-
end
|
870
|
-
|
871
927
|
# Returns a <tt>Relation</tt> object for the records in this association
|
872
928
|
def scope
|
873
|
-
@association.scope
|
929
|
+
@scope ||= @association.scope
|
874
930
|
end
|
875
|
-
alias spawn scope
|
876
931
|
|
877
932
|
# Equivalent to <tt>Array#==</tt>. Returns +true+ if the two arrays
|
878
933
|
# contain the same number of elements and if each element is equal
|
@@ -902,6 +957,12 @@ module ActiveRecord
|
|
902
957
|
load_target == other
|
903
958
|
end
|
904
959
|
|
960
|
+
##
|
961
|
+
# :method: to_ary
|
962
|
+
#
|
963
|
+
# :call-seq:
|
964
|
+
# to_ary()
|
965
|
+
#
|
905
966
|
# Returns a new array of objects from the collection. If the collection
|
906
967
|
# hasn't been loaded, it fetches the records from the database.
|
907
968
|
#
|
@@ -935,14 +996,15 @@ module ActiveRecord
|
|
935
996
|
# # #<Pet id: 5, name: "Brain", person_id: 1>,
|
936
997
|
# # #<Pet id: 6, name: "Boss", person_id: 1>
|
937
998
|
# # ]
|
938
|
-
|
939
|
-
|
999
|
+
|
1000
|
+
def records # :nodoc:
|
1001
|
+
load_target
|
940
1002
|
end
|
941
|
-
alias_method :to_a, :to_ary
|
942
1003
|
|
943
1004
|
# Adds one or more +records+ to the collection by setting their foreign keys
|
944
|
-
# to the association's primary key.
|
945
|
-
#
|
1005
|
+
# to the association's primary key. Since <tt><<</tt> flattens its argument list and
|
1006
|
+
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
|
1007
|
+
# so several appends may be chained together.
|
946
1008
|
#
|
947
1009
|
# class Person < ActiveRecord::Base
|
948
1010
|
# has_many :pets
|
@@ -965,21 +1027,24 @@ module ActiveRecord
|
|
965
1027
|
end
|
966
1028
|
alias_method :push, :<<
|
967
1029
|
alias_method :append, :<<
|
1030
|
+
alias_method :concat, :<<
|
968
1031
|
|
969
|
-
def prepend(*args)
|
970
|
-
raise NoMethodError, "prepend on association is not defined. Please use
|
1032
|
+
def prepend(*args) # :nodoc:
|
1033
|
+
raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"
|
971
1034
|
end
|
972
1035
|
|
973
1036
|
# Equivalent to +delete_all+. The difference is that returns +self+, instead
|
974
1037
|
# of an array with the deleted objects, so methods can be chained. See
|
975
1038
|
# +delete_all+ for more information.
|
1039
|
+
# Note that because +delete_all+ removes records by directly
|
1040
|
+
# running an SQL query into the database, the +updated_at+ column of
|
1041
|
+
# the object is not changed.
|
976
1042
|
def clear
|
977
1043
|
delete_all
|
978
1044
|
self
|
979
1045
|
end
|
980
1046
|
|
981
1047
|
# Reloads the collection from the database. Returns +self+.
|
982
|
-
# Equivalent to <tt>collection(true)</tt>.
|
983
1048
|
#
|
984
1049
|
# class Person < ActiveRecord::Base
|
985
1050
|
# has_many :pets
|
@@ -993,12 +1058,9 @@ module ActiveRecord
|
|
993
1058
|
#
|
994
1059
|
# person.pets.reload # fetches pets from the database
|
995
1060
|
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
996
|
-
#
|
997
|
-
# person.pets(true) # fetches pets from the database
|
998
|
-
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
999
1061
|
def reload
|
1000
|
-
proxy_association.reload
|
1001
|
-
|
1062
|
+
proxy_association.reload(true)
|
1063
|
+
reset_scope
|
1002
1064
|
end
|
1003
1065
|
|
1004
1066
|
# Unloads the association. Returns +self+.
|
@@ -1020,8 +1082,47 @@ module ActiveRecord
|
|
1020
1082
|
def reset
|
1021
1083
|
proxy_association.reset
|
1022
1084
|
proxy_association.reset_scope
|
1085
|
+
reset_scope
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
def reset_scope # :nodoc:
|
1089
|
+
@offsets = {}
|
1090
|
+
@scope = nil
|
1023
1091
|
self
|
1024
1092
|
end
|
1093
|
+
|
1094
|
+
delegate_methods = [
|
1095
|
+
QueryMethods,
|
1096
|
+
SpawnMethods,
|
1097
|
+
].flat_map { |klass|
|
1098
|
+
klass.public_instance_methods(false)
|
1099
|
+
} - self.public_instance_methods(false) - [:select] + [:scoping, :values]
|
1100
|
+
|
1101
|
+
delegate(*delegate_methods, to: :scope)
|
1102
|
+
|
1103
|
+
private
|
1104
|
+
|
1105
|
+
def find_nth_with_limit(index, limit)
|
1106
|
+
load_target if find_from_target?
|
1107
|
+
super
|
1108
|
+
end
|
1109
|
+
|
1110
|
+
def find_nth_from_last(index)
|
1111
|
+
load_target if find_from_target?
|
1112
|
+
super
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
def null_scope?
|
1116
|
+
@association.null_scope?
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
def find_from_target?
|
1120
|
+
@association.find_from_target?
|
1121
|
+
end
|
1122
|
+
|
1123
|
+
def exec_queries
|
1124
|
+
load_target
|
1125
|
+
end
|
1025
1126
|
end
|
1026
1127
|
end
|
1027
1128
|
end
|