activerecord 4.2.11.2 → 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 +4 -4
- data/CHANGELOG.md +613 -1638
- 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.rb +41 -22
- data/lib/active_record/aggregations.rb +267 -251
- data/lib/active_record/association_relation.rb +11 -6
- data/lib/active_record/associations.rb +1737 -1597
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +125 -58
- data/lib/active_record/associations/association_scope.rb +103 -132
- data/lib/active_record/associations/belongs_to_association.rb +65 -60
- 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 -33
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
- 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 +131 -287
- data/lib/active_record/associations/collection_proxy.rb +241 -146
- data/lib/active_record/associations/foreign_association.rb +10 -1
- data/lib/active_record/associations/has_many_association.rb +34 -97
- data/lib/active_record/associations/has_many_through_association.rb +60 -87
- data/lib/active_record/associations/has_one_association.rb +61 -49
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +137 -167
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
- 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/preloader.rb +90 -92
- data/lib/active_record/associations/preloader/association.rb +90 -123
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/singular_association.rb +18 -39
- data/lib/active_record/associations/through_association.rb +38 -18
- data/lib/active_record/attribute_assignment.rb +56 -183
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods.rb +120 -135
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
- data/lib/active_record/attribute_methods/dirty.rb +174 -144
- 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 +58 -36
- data/lib/active_record/attribute_methods/write.rb +32 -54
- data/lib/active_record/attributes.rb +214 -82
- data/lib/active_record/autosave_association.rb +91 -37
- data/lib/active_record/base.rb +57 -45
- 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 -296
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -243
- data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
- data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -635
- 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 +58 -180
- data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -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 +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 -22
- 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 +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 -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 +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/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 +470 -290
- 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 +551 -356
- 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 +290 -345
- 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 +251 -231
- data/lib/active_record/counter_cache.rb +67 -49
- data/lib/active_record/database_configurations.rb +233 -0
- 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/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +163 -86
- data/lib/active_record/errors.rb +188 -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 +10 -5
- 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 +228 -499
- data/lib/active_record/gem_version.rb +6 -4
- 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 +21 -3
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +87 -96
- 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.rb +75 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +621 -303
- 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/model_schema.rb +312 -112
- data/lib/active_record/nested_attributes.rb +264 -222
- data/lib/active_record/no_touching.rb +14 -1
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +557 -125
- data/lib/active_record/query_cache.rb +19 -23
- data/lib/active_record/querying.rb +43 -29
- data/lib/active_record/railtie.rb +143 -44
- 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 +328 -185
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +428 -279
- data/lib/active_record/relation.rb +518 -341
- data/lib/active_record/relation/batches.rb +207 -55
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/calculations.rb +267 -253
- data/lib/active_record/relation/delegation.rb +70 -80
- data/lib/active_record/relation/finder_methods.rb +277 -241
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +78 -87
- data/lib/active_record/relation/predicate_builder.rb +114 -119
- data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
- 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/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +575 -394
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +11 -13
- 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/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 -17
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/scoping/default.rb +101 -85
- data/lib/active_record/scoping/named.rb +86 -33
- 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 +307 -100
- data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
- data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
- 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 +216 -150
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +78 -23
- data/lib/active_record/type/adapter_specific_registry.rb +129 -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 -3
- 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 +24 -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_caster.rb +9 -0
- data/lib/active_record/type_caster/connection.rb +34 -0
- data/lib/active_record/type_caster/map.rb +20 -0
- data/lib/active_record/validations.rb +39 -35
- 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 +42 -55
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +51 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/attributes/attribute.rb +37 -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.rb +68 -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/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.rb +20 -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/window_predications.rb +9 -0
- data/lib/rails/generators/active_record.rb +7 -5
- 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.rb +31 -1
- 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 -2
- 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/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +164 -59
- 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_set.rb +0 -81
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
- 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 -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,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,27 +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
|
-
delegate :find_nth, to: :scope
|
33
|
-
|
34
30
|
def initialize(klass, association) #:nodoc:
|
35
31
|
@association = association
|
36
|
-
super klass
|
37
|
-
|
32
|
+
super klass
|
33
|
+
|
34
|
+
extensions = association.extensions
|
35
|
+
extend(*extensions) if extensions.any?
|
38
36
|
end
|
39
37
|
|
40
38
|
def target
|
@@ -54,6 +52,12 @@ module ActiveRecord
|
|
54
52
|
@association.loaded?
|
55
53
|
end
|
56
54
|
|
55
|
+
##
|
56
|
+
# :method: select
|
57
|
+
#
|
58
|
+
# :call-seq:
|
59
|
+
# select(*fields, &block)
|
60
|
+
#
|
57
61
|
# Works in two ways.
|
58
62
|
#
|
59
63
|
# *First:* Specify a subset of fields to be selected from the result set.
|
@@ -76,7 +80,7 @@ module ActiveRecord
|
|
76
80
|
# # #<Pet id: nil, name: "Choo-Choo">
|
77
81
|
# # ]
|
78
82
|
#
|
79
|
-
# person.pets.select(:id, :name
|
83
|
+
# person.pets.select(:id, :name)
|
80
84
|
# # => [
|
81
85
|
# # #<Pet id: 1, name: "Fancy-Fancy">,
|
82
86
|
# # #<Pet id: 2, name: "Spook">,
|
@@ -101,18 +105,9 @@ module ActiveRecord
|
|
101
105
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
102
106
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
103
107
|
# # ]
|
104
|
-
#
|
105
|
-
# person.pets.select(:name) { |pet| pet.name =~ /oo/ }
|
106
|
-
# # => [
|
107
|
-
# # #<Pet id: 2, name: "Spook">,
|
108
|
-
# # #<Pet id: 3, name: "Choo-Choo">
|
109
|
-
# # ]
|
110
|
-
def select(*fields, &block)
|
111
|
-
@association.select(*fields, &block)
|
112
|
-
end
|
113
108
|
|
114
109
|
# Finds an object in the collection responding to the +id+. Uses the same
|
115
|
-
# rules as
|
110
|
+
# rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound
|
116
111
|
# error if the object cannot be found.
|
117
112
|
#
|
118
113
|
# class Person < ActiveRecord::Base
|
@@ -127,7 +122,7 @@ module ActiveRecord
|
|
127
122
|
# # ]
|
128
123
|
#
|
129
124
|
# person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
|
130
|
-
# 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
|
131
126
|
#
|
132
127
|
# person.pets.find(2) { |pet| pet.name.downcase! }
|
133
128
|
# # => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
|
@@ -137,10 +132,17 @@ module ActiveRecord
|
|
137
132
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
138
133
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
139
134
|
# # ]
|
140
|
-
def find(*args
|
141
|
-
|
135
|
+
def find(*args)
|
136
|
+
return super if block_given?
|
137
|
+
@association.find(*args)
|
142
138
|
end
|
143
139
|
|
140
|
+
##
|
141
|
+
# :method: first
|
142
|
+
#
|
143
|
+
# :call-seq:
|
144
|
+
# first(limit = nil)
|
145
|
+
#
|
144
146
|
# Returns the first record, or the first +n+ records, from the collection.
|
145
147
|
# If the collection is empty, the first form returns +nil+, and the second
|
146
148
|
# form returns an empty array.
|
@@ -167,35 +169,63 @@ module ActiveRecord
|
|
167
169
|
# another_person_without.pets # => []
|
168
170
|
# another_person_without.pets.first # => nil
|
169
171
|
# another_person_without.pets.first(3) # => []
|
170
|
-
def first(*args)
|
171
|
-
@association.first(*args)
|
172
|
-
end
|
173
172
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
173
|
+
##
|
174
|
+
# :method: second
|
175
|
+
#
|
176
|
+
# :call-seq:
|
177
|
+
# second()
|
178
|
+
#
|
179
|
+
# Same as #first except returns only the second record.
|
178
180
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
181
|
+
##
|
182
|
+
# :method: third
|
183
|
+
#
|
184
|
+
# :call-seq:
|
185
|
+
# third()
|
186
|
+
#
|
187
|
+
# Same as #first except returns only the third record.
|
183
188
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
189
|
+
##
|
190
|
+
# :method: fourth
|
191
|
+
#
|
192
|
+
# :call-seq:
|
193
|
+
# fourth()
|
194
|
+
#
|
195
|
+
# Same as #first except returns only the fourth record.
|
188
196
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
197
|
+
##
|
198
|
+
# :method: fifth
|
199
|
+
#
|
200
|
+
# :call-seq:
|
201
|
+
# fifth()
|
202
|
+
#
|
203
|
+
# Same as #first except returns only the fifth record.
|
193
204
|
|
194
|
-
|
205
|
+
##
|
206
|
+
# :method: forty_two
|
207
|
+
#
|
208
|
+
# :call-seq:
|
209
|
+
# forty_two()
|
210
|
+
#
|
211
|
+
# Same as #first except returns only the forty second record.
|
195
212
|
# Also known as accessing "the reddit".
|
196
|
-
|
197
|
-
|
198
|
-
|
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.
|
199
229
|
|
200
230
|
# Returns the last record, or the last +n+ records, from the collection.
|
201
231
|
# If the collection is empty, the first form returns +nil+, and the second
|
@@ -223,12 +253,39 @@ module ActiveRecord
|
|
223
253
|
# another_person_without.pets # => []
|
224
254
|
# another_person_without.pets.last # => nil
|
225
255
|
# another_person_without.pets.last(3) # => []
|
226
|
-
def last(
|
227
|
-
|
256
|
+
def last(limit = nil)
|
257
|
+
load_target if find_from_target?
|
258
|
+
super
|
228
259
|
end
|
229
260
|
|
230
|
-
|
231
|
-
|
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
|
232
289
|
end
|
233
290
|
|
234
291
|
# Returns a new object of the collection type that has been instantiated
|
@@ -290,7 +347,7 @@ module ActiveRecord
|
|
290
347
|
@association.create(attributes, &block)
|
291
348
|
end
|
292
349
|
|
293
|
-
# Like
|
350
|
+
# Like #create, except that if the record is invalid, raises an exception.
|
294
351
|
#
|
295
352
|
# class Person
|
296
353
|
# has_many :pets
|
@@ -306,34 +363,6 @@ module ActiveRecord
|
|
306
363
|
@association.create!(attributes, &block)
|
307
364
|
end
|
308
365
|
|
309
|
-
# Add one or more records to the collection by setting their foreign keys
|
310
|
-
# to the association's primary key. Since << flattens its argument list and
|
311
|
-
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
|
312
|
-
# so method calls may be chained.
|
313
|
-
#
|
314
|
-
# class Person < ActiveRecord::Base
|
315
|
-
# has_many :pets
|
316
|
-
# end
|
317
|
-
#
|
318
|
-
# person.pets.size # => 0
|
319
|
-
# person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
|
320
|
-
# person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo'))
|
321
|
-
# person.pets.size # => 3
|
322
|
-
#
|
323
|
-
# person.id # => 1
|
324
|
-
# person.pets
|
325
|
-
# # => [
|
326
|
-
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
327
|
-
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
328
|
-
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
329
|
-
# # ]
|
330
|
-
#
|
331
|
-
# person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
|
332
|
-
# person.pets.size # => 5
|
333
|
-
def concat(*records)
|
334
|
-
@association.concat(*records)
|
335
|
-
end
|
336
|
-
|
337
366
|
# Replaces this collection with +other_array+. This will perform a diff
|
338
367
|
# and delete/add only records that have changed.
|
339
368
|
#
|
@@ -364,7 +393,7 @@ module ActiveRecord
|
|
364
393
|
# specified by the +:dependent+ option. If no +:dependent+ option is given,
|
365
394
|
# then it will follow the default strategy.
|
366
395
|
#
|
367
|
-
# For
|
396
|
+
# For <tt>has_many :through</tt> associations, the default deletion strategy is
|
368
397
|
# +:delete_all+.
|
369
398
|
#
|
370
399
|
# For +has_many+ associations, the default deletion strategy is +:nullify+.
|
@@ -399,7 +428,7 @@ module ActiveRecord
|
|
399
428
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: nil>
|
400
429
|
# # ]
|
401
430
|
#
|
402
|
-
# Both +has_many+ and
|
431
|
+
# Both +has_many+ and <tt>has_many :through</tt> dependencies default to the
|
403
432
|
# +:delete_all+ strategy if the +:dependent+ option is set to +:destroy+.
|
404
433
|
# Records are not instantiated and callbacks will not be fired.
|
405
434
|
#
|
@@ -418,7 +447,7 @@ module ActiveRecord
|
|
418
447
|
# person.pets.delete_all
|
419
448
|
#
|
420
449
|
# Pet.find(1, 2, 3)
|
421
|
-
# # => ActiveRecord::RecordNotFound
|
450
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
|
422
451
|
#
|
423
452
|
# If it is set to <tt>:delete_all</tt>, all the objects are deleted
|
424
453
|
# *without* calling their +destroy+ method.
|
@@ -438,9 +467,9 @@ module ActiveRecord
|
|
438
467
|
# person.pets.delete_all
|
439
468
|
#
|
440
469
|
# Pet.find(1, 2, 3)
|
441
|
-
# # => ActiveRecord::RecordNotFound
|
470
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
|
442
471
|
def delete_all(dependent = nil)
|
443
|
-
@association.delete_all(dependent)
|
472
|
+
@association.delete_all(dependent).tap { reset_scope }
|
444
473
|
end
|
445
474
|
|
446
475
|
# Deletes the records of the collection directly from the database
|
@@ -467,7 +496,7 @@ module ActiveRecord
|
|
467
496
|
#
|
468
497
|
# Pet.find(1) # => Couldn't find Pet with id=1
|
469
498
|
def destroy_all
|
470
|
-
@association.destroy_all
|
499
|
+
@association.destroy_all.tap { reset_scope }
|
471
500
|
end
|
472
501
|
|
473
502
|
# Deletes the +records+ supplied from the collection according to the strategy
|
@@ -475,7 +504,7 @@ module ActiveRecord
|
|
475
504
|
# then it will follow the default strategy. Returns an array with the
|
476
505
|
# deleted records.
|
477
506
|
#
|
478
|
-
# For
|
507
|
+
# For <tt>has_many :through</tt> associations, the default deletion strategy is
|
479
508
|
# +:delete_all+.
|
480
509
|
#
|
481
510
|
# For +has_many+ associations, the default deletion strategy is +:nullify+.
|
@@ -532,7 +561,7 @@ module ActiveRecord
|
|
532
561
|
# # => [#<Pet id: 2, name: "Spook", person_id: 1>]
|
533
562
|
#
|
534
563
|
# Pet.find(1, 3)
|
535
|
-
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with
|
564
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
|
536
565
|
#
|
537
566
|
# If it is set to <tt>:delete_all</tt>, all the +records+ are deleted
|
538
567
|
# *without* calling their +destroy+ method.
|
@@ -560,7 +589,7 @@ module ActiveRecord
|
|
560
589
|
# # ]
|
561
590
|
#
|
562
591
|
# Pet.find(1)
|
563
|
-
# # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=1
|
592
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
|
564
593
|
#
|
565
594
|
# You can pass +Integer+ or +String+ values, it finds the records
|
566
595
|
# responding to the +id+ and executes delete on them.
|
@@ -586,7 +615,7 @@ module ActiveRecord
|
|
586
615
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
587
616
|
# # ]
|
588
617
|
def delete(*records)
|
589
|
-
@association.delete(*records)
|
618
|
+
@association.delete(*records).tap { reset_scope }
|
590
619
|
end
|
591
620
|
|
592
621
|
# Destroys the +records+ supplied and removes them from the collection.
|
@@ -624,7 +653,7 @@ module ActiveRecord
|
|
624
653
|
# person.pets.size # => 0
|
625
654
|
# person.pets # => []
|
626
655
|
#
|
627
|
-
# 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)
|
628
657
|
#
|
629
658
|
# You can pass +Integer+ or +String+ values, it finds the records
|
630
659
|
# responding to the +id+ and then deletes them from the database.
|
@@ -656,11 +685,17 @@ module ActiveRecord
|
|
656
685
|
# person.pets.size # => 0
|
657
686
|
# person.pets # => []
|
658
687
|
#
|
659
|
-
# 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)
|
660
689
|
def destroy(*records)
|
661
|
-
@association.destroy(*records)
|
690
|
+
@association.destroy(*records).tap { reset_scope }
|
662
691
|
end
|
663
692
|
|
693
|
+
##
|
694
|
+
# :method: distinct
|
695
|
+
#
|
696
|
+
# :call-seq:
|
697
|
+
# distinct(value = true)
|
698
|
+
#
|
664
699
|
# Specifies whether the records should be unique or not.
|
665
700
|
#
|
666
701
|
# class Person < ActiveRecord::Base
|
@@ -675,17 +710,35 @@ module ActiveRecord
|
|
675
710
|
#
|
676
711
|
# person.pets.select(:name).distinct
|
677
712
|
# # => [#<Pet name: "Fancy-Fancy">]
|
678
|
-
|
679
|
-
|
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
|
723
|
+
end
|
724
|
+
|
725
|
+
def pluck(*column_names)
|
726
|
+
null_scope? ? scope.pluck(*column_names) : super
|
680
727
|
end
|
681
|
-
alias uniq distinct
|
682
728
|
|
683
|
-
|
729
|
+
##
|
730
|
+
# :method: count
|
731
|
+
#
|
732
|
+
# :call-seq:
|
733
|
+
# count(column_name = nil, &block)
|
734
|
+
#
|
735
|
+
# Count all records.
|
684
736
|
#
|
685
737
|
# class Person < ActiveRecord::Base
|
686
738
|
# has_many :pets
|
687
739
|
# end
|
688
740
|
#
|
741
|
+
# # This will perform the count using SQL.
|
689
742
|
# person.pets.count # => 3
|
690
743
|
# person.pets
|
691
744
|
# # => [
|
@@ -693,11 +746,11 @@ module ActiveRecord
|
|
693
746
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
694
747
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
695
748
|
# # ]
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
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
|
701
754
|
|
702
755
|
# Returns the size of the collection. If the collection hasn't been loaded,
|
703
756
|
# it executes a <tt>SELECT COUNT(*)</tt> query. Else it calls <tt>collection.size</tt>.
|
@@ -727,6 +780,12 @@ module ActiveRecord
|
|
727
780
|
@association.size
|
728
781
|
end
|
729
782
|
|
783
|
+
##
|
784
|
+
# :method: length
|
785
|
+
#
|
786
|
+
# :call-seq:
|
787
|
+
# length()
|
788
|
+
#
|
730
789
|
# Returns the size of the collection calling +size+ on the target.
|
731
790
|
# If the collection has been already loaded, +length+ and +size+ are
|
732
791
|
# equivalent. If not and you are going to need the records anyway this
|
@@ -747,14 +806,11 @@ module ActiveRecord
|
|
747
806
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
748
807
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
749
808
|
# # ]
|
750
|
-
def length
|
751
|
-
@association.length
|
752
|
-
end
|
753
809
|
|
754
810
|
# Returns +true+ if the collection is empty. If the collection has been
|
755
811
|
# loaded it is equivalent
|
756
812
|
# to <tt>collection.size.zero?</tt>. If the collection has not been loaded,
|
757
|
-
# it is equivalent to <tt
|
813
|
+
# it is equivalent to <tt>!collection.exists?</tt>. If the collection has
|
758
814
|
# not already been loaded and you are going to fetch the records anyway it
|
759
815
|
# is better to check <tt>collection.length.zero?</tt>.
|
760
816
|
#
|
@@ -773,6 +829,12 @@ module ActiveRecord
|
|
773
829
|
@association.empty?
|
774
830
|
end
|
775
831
|
|
832
|
+
##
|
833
|
+
# :method: any?
|
834
|
+
#
|
835
|
+
# :call-seq:
|
836
|
+
# any?()
|
837
|
+
#
|
776
838
|
# Returns +true+ if the collection is not empty.
|
777
839
|
#
|
778
840
|
# class Person < ActiveRecord::Base
|
@@ -783,7 +845,7 @@ module ActiveRecord
|
|
783
845
|
# person.pets.any? # => false
|
784
846
|
#
|
785
847
|
# person.pets << Pet.new(name: 'Snoop')
|
786
|
-
# person.pets.count # =>
|
848
|
+
# person.pets.count # => 1
|
787
849
|
# person.pets.any? # => true
|
788
850
|
#
|
789
851
|
# You can also pass a +block+ to define criteria. The behavior
|
@@ -802,10 +864,13 @@ module ActiveRecord
|
|
802
864
|
# pet.group == 'dogs'
|
803
865
|
# end
|
804
866
|
# # => true
|
805
|
-
def any?(&block)
|
806
|
-
@association.any?(&block)
|
807
|
-
end
|
808
867
|
|
868
|
+
##
|
869
|
+
# :method: many?
|
870
|
+
#
|
871
|
+
# :call-seq:
|
872
|
+
# many?()
|
873
|
+
#
|
809
874
|
# Returns true if the collection has more than one record.
|
810
875
|
# Equivalent to <tt>collection.size > 1</tt>.
|
811
876
|
#
|
@@ -840,9 +905,6 @@ module ActiveRecord
|
|
840
905
|
# pet.group == 'cats'
|
841
906
|
# end
|
842
907
|
# # => true
|
843
|
-
def many?(&block)
|
844
|
-
@association.many?(&block)
|
845
|
-
end
|
846
908
|
|
847
909
|
# Returns +true+ if the given +record+ is present in the collection.
|
848
910
|
#
|
@@ -858,27 +920,14 @@ module ActiveRecord
|
|
858
920
|
!!@association.include?(record)
|
859
921
|
end
|
860
922
|
|
861
|
-
def arel
|
862
|
-
scope.arel
|
863
|
-
end
|
864
|
-
|
865
923
|
def proxy_association
|
866
924
|
@association
|
867
925
|
end
|
868
926
|
|
869
|
-
# We don't want this object to be put on the scoping stack, because
|
870
|
-
# that could create an infinite loop where we call an @association
|
871
|
-
# method, which gets the current scope, which is this object, which
|
872
|
-
# delegates to @association, and so on.
|
873
|
-
def scoping
|
874
|
-
@association.scope.scoping { yield }
|
875
|
-
end
|
876
|
-
|
877
927
|
# Returns a <tt>Relation</tt> object for the records in this association
|
878
928
|
def scope
|
879
|
-
@association.scope
|
929
|
+
@scope ||= @association.scope
|
880
930
|
end
|
881
|
-
alias spawn scope
|
882
931
|
|
883
932
|
# Equivalent to <tt>Array#==</tt>. Returns +true+ if the two arrays
|
884
933
|
# contain the same number of elements and if each element is equal
|
@@ -908,6 +957,12 @@ module ActiveRecord
|
|
908
957
|
load_target == other
|
909
958
|
end
|
910
959
|
|
960
|
+
##
|
961
|
+
# :method: to_ary
|
962
|
+
#
|
963
|
+
# :call-seq:
|
964
|
+
# to_ary()
|
965
|
+
#
|
911
966
|
# Returns a new array of objects from the collection. If the collection
|
912
967
|
# hasn't been loaded, it fetches the records from the database.
|
913
968
|
#
|
@@ -941,14 +996,15 @@ module ActiveRecord
|
|
941
996
|
# # #<Pet id: 5, name: "Brain", person_id: 1>,
|
942
997
|
# # #<Pet id: 6, name: "Boss", person_id: 1>
|
943
998
|
# # ]
|
944
|
-
|
945
|
-
|
999
|
+
|
1000
|
+
def records # :nodoc:
|
1001
|
+
load_target
|
946
1002
|
end
|
947
|
-
alias_method :to_a, :to_ary
|
948
1003
|
|
949
1004
|
# Adds one or more +records+ to the collection by setting their foreign keys
|
950
|
-
# to the association's primary key.
|
951
|
-
#
|
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.
|
952
1008
|
#
|
953
1009
|
# class Person < ActiveRecord::Base
|
954
1010
|
# has_many :pets
|
@@ -971,21 +1027,24 @@ module ActiveRecord
|
|
971
1027
|
end
|
972
1028
|
alias_method :push, :<<
|
973
1029
|
alias_method :append, :<<
|
1030
|
+
alias_method :concat, :<<
|
974
1031
|
|
975
|
-
def prepend(*args)
|
976
|
-
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"
|
977
1034
|
end
|
978
1035
|
|
979
1036
|
# Equivalent to +delete_all+. The difference is that returns +self+, instead
|
980
1037
|
# of an array with the deleted objects, so methods can be chained. See
|
981
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.
|
982
1042
|
def clear
|
983
1043
|
delete_all
|
984
1044
|
self
|
985
1045
|
end
|
986
1046
|
|
987
1047
|
# Reloads the collection from the database. Returns +self+.
|
988
|
-
# Equivalent to <tt>collection(true)</tt>.
|
989
1048
|
#
|
990
1049
|
# class Person < ActiveRecord::Base
|
991
1050
|
# has_many :pets
|
@@ -999,12 +1058,9 @@ module ActiveRecord
|
|
999
1058
|
#
|
1000
1059
|
# person.pets.reload # fetches pets from the database
|
1001
1060
|
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
1002
|
-
#
|
1003
|
-
# person.pets(true) # fetches pets from the database
|
1004
|
-
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
1005
1061
|
def reload
|
1006
|
-
proxy_association.reload
|
1007
|
-
|
1062
|
+
proxy_association.reload(true)
|
1063
|
+
reset_scope
|
1008
1064
|
end
|
1009
1065
|
|
1010
1066
|
# Unloads the association. Returns +self+.
|
@@ -1026,8 +1082,47 @@ module ActiveRecord
|
|
1026
1082
|
def reset
|
1027
1083
|
proxy_association.reset
|
1028
1084
|
proxy_association.reset_scope
|
1085
|
+
reset_scope
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
def reset_scope # :nodoc:
|
1089
|
+
@offsets = {}
|
1090
|
+
@scope = nil
|
1029
1091
|
self
|
1030
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
|
1031
1126
|
end
|
1032
1127
|
end
|
1033
1128
|
end
|