activerecord 4.2.9 → 6.1.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +964 -1382
- data/MIT-LICENSE +4 -2
- data/README.rdoc +15 -14
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +266 -251
- data/lib/active_record/association_relation.rb +40 -15
- data/lib/active_record/associations/alias_tracker.rb +40 -43
- data/lib/active_record/associations/association.rb +162 -69
- data/lib/active_record/associations/association_scope.rb +105 -130
- data/lib/active_record/associations/belongs_to_association.rb +83 -65
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
- data/lib/active_record/associations/builder/association.rb +57 -43
- data/lib/active_record/associations/builder/belongs_to.rb +74 -57
- data/lib/active_record/associations/builder/collection_association.rb +15 -37
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
- data/lib/active_record/associations/builder/has_many.rb +13 -5
- data/lib/active_record/associations/builder/has_one.rb +44 -6
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +148 -287
- data/lib/active_record/associations/collection_proxy.rb +252 -150
- data/lib/active_record/associations/foreign_association.rb +23 -1
- data/lib/active_record/associations/has_many_association.rb +56 -98
- data/lib/active_record/associations/has_many_through_association.rb +68 -89
- data/lib/active_record/associations/has_one_association.rb +73 -47
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/join_dependency.rb +174 -169
- data/lib/active_record/associations/preloader/association.rb +108 -115
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +97 -94
- data/lib/active_record/associations/singular_association.rb +18 -39
- data/lib/active_record/associations/through_association.rb +39 -19
- data/lib/active_record/associations.rb +1845 -1598
- data/lib/active_record/attribute_assignment.rb +59 -185
- data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
- data/lib/active_record/attribute_methods/dirty.rb +168 -148
- data/lib/active_record/attribute_methods/primary_key.rb +93 -83
- data/lib/active_record/attribute_methods/query.rb +8 -10
- data/lib/active_record/attribute_methods/read.rb +19 -79
- data/lib/active_record/attribute_methods/serialization.rb +49 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
- data/lib/active_record/attribute_methods/write.rb +24 -55
- data/lib/active_record/attribute_methods.rb +149 -154
- data/lib/active_record/attributes.rb +234 -78
- data/lib/active_record/autosave_association.rb +133 -60
- data/lib/active_record/base.rb +46 -46
- data/lib/active_record/callbacks.rb +234 -79
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +34 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
- data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
- data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
- data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
- data/lib/active_record/connection_adapters/column.rb +67 -40
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
- data/lib/active_record/connection_adapters/pool_config.rb +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
- data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
- data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
- data/lib/active_record/connection_adapters.rb +52 -0
- data/lib/active_record/connection_handling.rb +314 -41
- data/lib/active_record/core.rb +458 -241
- data/lib/active_record/counter_cache.rb +70 -49
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/database_configurations.rb +272 -0
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +87 -106
- data/lib/active_record/enum.rb +211 -92
- data/lib/active_record/errors.rb +224 -54
- data/lib/active_record/explain.rb +27 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +33 -14
- data/lib/active_record/fixture_set/model_metadata.rb +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +275 -500
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +175 -110
- data/lib/active_record/insert_all.rb +212 -0
- data/lib/active_record/integration.rb +121 -29
- data/lib/active_record/internal_metadata.rb +62 -0
- data/lib/active_record/legacy_yaml_adapter.rb +27 -5
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +98 -92
- data/lib/active_record/locking/pessimistic.rb +22 -6
- data/lib/active_record/log_subscriber.rb +93 -31
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/migration/command_recorder.rb +185 -90
- data/lib/active_record/migration/compatibility.rb +295 -0
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/migration.rb +673 -325
- data/lib/active_record/model_schema.rb +418 -113
- data/lib/active_record/nested_attributes.rb +263 -224
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -38
- data/lib/active_record/persistence.rb +572 -136
- data/lib/active_record/query_cache.rb +29 -23
- data/lib/active_record/querying.rb +50 -31
- data/lib/active_record/railtie.rb +170 -51
- data/lib/active_record/railties/console_sandbox.rb +3 -3
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +523 -199
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +454 -291
- data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
- data/lib/active_record/relation/batches.rb +217 -59
- data/lib/active_record/relation/calculations.rb +324 -249
- data/lib/active_record/relation/delegation.rb +76 -84
- data/lib/active_record/relation/finder_methods.rb +316 -242
- data/lib/active_record/relation/from_clause.rb +30 -0
- data/lib/active_record/relation/merger.rb +95 -103
- data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +136 -122
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +757 -413
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -20
- data/lib/active_record/relation/where_clause.rb +239 -0
- data/lib/active_record/relation.rb +554 -343
- data/lib/active_record/result.rb +91 -47
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +134 -122
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +141 -92
- data/lib/active_record/schema_migration.rb +24 -23
- data/lib/active_record/scoping/default.rb +96 -83
- data/lib/active_record/scoping/named.rb +78 -36
- data/lib/active_record/scoping.rb +45 -27
- data/lib/active_record/secure_token.rb +48 -0
- data/lib/active_record/serialization.rb +8 -6
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +89 -36
- data/lib/active_record/store.rb +128 -43
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +81 -0
- data/lib/active_record/tasks/database_tasks.rb +364 -130
- data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
- data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
- data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +287 -0
- data/lib/active_record/timestamp.rb +86 -43
- data/lib/active_record/touch_later.rb +65 -0
- data/lib/active_record/transactions.rb +182 -163
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +126 -0
- data/lib/active_record/type/date.rb +4 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +27 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +21 -16
- data/lib/active_record/type/type_map.rb +16 -19
- data/lib/active_record/type/unsigned_integer.rb +9 -8
- data/lib/active_record/type.rb +84 -23
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +12 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +63 -56
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +42 -29
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +76 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +70 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +54 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
- data/lib/rails/generators/active_record/migration.rb +35 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +172 -65
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -163
- data/lib/active_record/attribute_decorators.rb +0 -66
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -64
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
data/lib/active_record/core.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/enumerable"
|
4
|
+
require "active_support/core_ext/hash/indifferent_access"
|
5
|
+
require "active_support/core_ext/string/filters"
|
6
|
+
require "active_support/parameter_filter"
|
7
|
+
require "concurrent/map"
|
5
8
|
|
6
9
|
module ActiveRecord
|
7
10
|
module Core
|
@@ -16,9 +19,28 @@ module ActiveRecord
|
|
16
19
|
# retrieved on both a class and instance level by calling +logger+.
|
17
20
|
mattr_accessor :logger, instance_writer: false
|
18
21
|
|
22
|
+
##
|
23
|
+
# :singleton-method:
|
24
|
+
#
|
25
|
+
# Specifies if the methods calling database queries should be logged below
|
26
|
+
# their relevant queries. Defaults to false.
|
27
|
+
mattr_accessor :verbose_query_logs, instance_writer: false, default: false
|
28
|
+
|
29
|
+
##
|
30
|
+
# :singleton-method:
|
31
|
+
#
|
32
|
+
# Specifies the names of the queues used by background jobs.
|
33
|
+
mattr_accessor :queues, instance_accessor: false, default: {}
|
34
|
+
|
35
|
+
##
|
36
|
+
# :singleton-method:
|
37
|
+
#
|
38
|
+
# Specifies the job used to destroy associations in the background
|
39
|
+
class_attribute :destroy_association_async_job, instance_writer: false, instance_predicate: false, default: false
|
40
|
+
|
19
41
|
##
|
20
42
|
# Contains the database configuration - as is typically stored in config/database.yml -
|
21
|
-
# as
|
43
|
+
# as an ActiveRecord::DatabaseConfigurations object.
|
22
44
|
#
|
23
45
|
# For example, the following database.yml...
|
24
46
|
#
|
@@ -32,22 +54,18 @@ module ActiveRecord
|
|
32
54
|
#
|
33
55
|
# ...would result in ActiveRecord::Base.configurations to look like this:
|
34
56
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
# 'adapter' => 'sqlite3',
|
42
|
-
# 'database' => 'db/production.sqlite3'
|
43
|
-
# }
|
44
|
-
# }
|
57
|
+
# #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
|
58
|
+
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
59
|
+
# @name="primary", @config={adapter: "sqlite3", database: "db/development.sqlite3"}>,
|
60
|
+
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
|
61
|
+
# @name="primary", @config={adapter: "sqlite3", database: "db/production.sqlite3"}>
|
62
|
+
# ]>
|
45
63
|
def self.configurations=(config)
|
46
|
-
@@configurations = ActiveRecord::
|
64
|
+
@@configurations = ActiveRecord::DatabaseConfigurations.new(config)
|
47
65
|
end
|
48
66
|
self.configurations = {}
|
49
67
|
|
50
|
-
# Returns fully resolved
|
68
|
+
# Returns fully resolved ActiveRecord::DatabaseConfigurations object
|
51
69
|
def self.configurations
|
52
70
|
@@configurations
|
53
71
|
end
|
@@ -56,8 +74,7 @@ module ActiveRecord
|
|
56
74
|
# :singleton-method:
|
57
75
|
# Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
|
58
76
|
# dates and times from the database. This is set to :utc by default.
|
59
|
-
mattr_accessor :default_timezone, instance_writer: false
|
60
|
-
self.default_timezone = :utc
|
77
|
+
mattr_accessor :default_timezone, instance_writer: false, default: :utc
|
61
78
|
|
62
79
|
##
|
63
80
|
# :singleton-method:
|
@@ -67,149 +84,348 @@ module ActiveRecord
|
|
67
84
|
# ActiveRecord::Schema file which can be loaded into any database that
|
68
85
|
# supports migrations. Use :ruby if you want to have different database
|
69
86
|
# adapters for, e.g., your development and test environments.
|
70
|
-
mattr_accessor :schema_format, instance_writer: false
|
71
|
-
|
87
|
+
mattr_accessor :schema_format, instance_writer: false, default: :ruby
|
88
|
+
|
89
|
+
##
|
90
|
+
# :singleton-method:
|
91
|
+
# Specifies if an error should be raised if the query has an order being
|
92
|
+
# ignored when doing batch queries. Useful in applications where the
|
93
|
+
# scope being ignored is error-worthy, rather than a warning.
|
94
|
+
mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
|
72
95
|
|
73
96
|
##
|
74
97
|
# :singleton-method:
|
75
98
|
# Specify whether or not to use timestamps for migration versions
|
76
|
-
mattr_accessor :timestamped_migrations, instance_writer: false
|
77
|
-
self.timestamped_migrations = true
|
99
|
+
mattr_accessor :timestamped_migrations, instance_writer: false, default: true
|
78
100
|
|
79
101
|
##
|
80
102
|
# :singleton-method:
|
81
103
|
# Specify whether schema dump should happen at the end of the
|
82
|
-
# db:migrate
|
104
|
+
# db:migrate rails command. This is true by default, which is useful for the
|
83
105
|
# development environment. This should ideally be false in the production
|
84
106
|
# environment where dumping schema is rarely needed.
|
85
|
-
mattr_accessor :dump_schema_after_migration, instance_writer: false
|
86
|
-
|
107
|
+
mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
|
108
|
+
|
109
|
+
##
|
110
|
+
# :singleton-method:
|
111
|
+
# Specifies which database schemas to dump when calling db:schema:dump.
|
112
|
+
# If the value is :schema_search_path (the default), any schemas listed in
|
113
|
+
# schema_search_path are dumped. Use :all to dump all schemas regardless
|
114
|
+
# of schema_search_path, or a string of comma separated schemas for a
|
115
|
+
# custom list.
|
116
|
+
mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
|
117
|
+
|
118
|
+
##
|
119
|
+
# :singleton-method:
|
120
|
+
# Specify a threshold for the size of query result sets. If the number of
|
121
|
+
# records in the set exceeds the threshold, a warning is logged. This can
|
122
|
+
# be used to identify queries which load thousands of records and
|
123
|
+
# potentially cause memory bloat.
|
124
|
+
mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
|
125
|
+
|
126
|
+
##
|
127
|
+
# :singleton-method:
|
128
|
+
# Show a warning when Rails couldn't parse your database.yml
|
129
|
+
# for multiple databases.
|
130
|
+
mattr_accessor :suppress_multiple_database_warning, instance_writer: false, default: false
|
87
131
|
|
88
132
|
mattr_accessor :maintain_test_schema, instance_accessor: false
|
89
133
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
134
|
+
class_attribute :belongs_to_required_by_default, instance_accessor: false
|
135
|
+
|
136
|
+
##
|
137
|
+
# :singleton-method:
|
138
|
+
# Set the application to log or raise when an association violates strict loading.
|
139
|
+
# Defaults to :raise.
|
140
|
+
mattr_accessor :action_on_strict_loading_violation, instance_accessor: false, default: :raise
|
141
|
+
|
142
|
+
class_attribute :strict_loading_by_default, instance_accessor: false, default: false
|
143
|
+
|
144
|
+
mattr_accessor :writing_role, instance_accessor: false, default: :writing
|
145
|
+
|
146
|
+
mattr_accessor :reading_role, instance_accessor: false, default: :reading
|
147
|
+
|
148
|
+
mattr_accessor :has_many_inversing, instance_accessor: false, default: false
|
96
149
|
|
97
150
|
class_attribute :default_connection_handler, instance_writer: false
|
98
|
-
|
151
|
+
|
152
|
+
class_attribute :default_role, instance_writer: false
|
153
|
+
|
154
|
+
class_attribute :default_shard, instance_writer: false
|
155
|
+
|
156
|
+
mattr_accessor :legacy_connection_handling, instance_writer: false, default: true
|
157
|
+
|
158
|
+
self.filter_attributes = []
|
99
159
|
|
100
160
|
def self.connection_handler
|
101
|
-
|
161
|
+
Thread.current.thread_variable_get(:ar_connection_handler) || default_connection_handler
|
102
162
|
end
|
103
163
|
|
104
164
|
def self.connection_handler=(handler)
|
105
|
-
|
165
|
+
Thread.current.thread_variable_set(:ar_connection_handler, handler)
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.connection_handlers
|
169
|
+
unless legacy_connection_handling
|
170
|
+
raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
|
171
|
+
end
|
172
|
+
|
173
|
+
@@connection_handlers ||= {}
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.connection_handlers=(handlers)
|
177
|
+
unless legacy_connection_handling
|
178
|
+
raise NotImplementedError, "The new connection handling does not setting support multiple connection handlers."
|
179
|
+
end
|
180
|
+
|
181
|
+
@@connection_handlers = handlers
|
182
|
+
end
|
183
|
+
|
184
|
+
# Returns the symbol representing the current connected role.
|
185
|
+
#
|
186
|
+
# ActiveRecord::Base.connected_to(role: :writing) do
|
187
|
+
# ActiveRecord::Base.current_role #=> :writing
|
188
|
+
# end
|
189
|
+
#
|
190
|
+
# ActiveRecord::Base.connected_to(role: :reading) do
|
191
|
+
# ActiveRecord::Base.current_role #=> :reading
|
192
|
+
# end
|
193
|
+
def self.current_role
|
194
|
+
if ActiveRecord::Base.legacy_connection_handling
|
195
|
+
connection_handlers.key(connection_handler) || default_role
|
196
|
+
else
|
197
|
+
connected_to_stack.reverse_each do |hash|
|
198
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
199
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_classes)
|
200
|
+
end
|
201
|
+
|
202
|
+
default_role
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# Returns the symbol representing the current connected shard.
|
207
|
+
#
|
208
|
+
# ActiveRecord::Base.connected_to(role: :reading) do
|
209
|
+
# ActiveRecord::Base.current_shard #=> :default
|
210
|
+
# end
|
211
|
+
#
|
212
|
+
# ActiveRecord::Base.connected_to(role: :writing, shard: :one) do
|
213
|
+
# ActiveRecord::Base.current_shard #=> :one
|
214
|
+
# end
|
215
|
+
def self.current_shard
|
216
|
+
connected_to_stack.reverse_each do |hash|
|
217
|
+
return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
|
218
|
+
return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_classes)
|
219
|
+
end
|
220
|
+
|
221
|
+
default_shard
|
222
|
+
end
|
223
|
+
|
224
|
+
# Returns the symbol representing the current setting for
|
225
|
+
# preventing writes.
|
226
|
+
#
|
227
|
+
# ActiveRecord::Base.connected_to(role: :reading) do
|
228
|
+
# ActiveRecord::Base.current_preventing_writes #=> true
|
229
|
+
# end
|
230
|
+
#
|
231
|
+
# ActiveRecord::Base.connected_to(role: :writing) do
|
232
|
+
# ActiveRecord::Base.current_preventing_writes #=> false
|
233
|
+
# end
|
234
|
+
def self.current_preventing_writes
|
235
|
+
if legacy_connection_handling
|
236
|
+
connection_handler.prevent_writes
|
237
|
+
else
|
238
|
+
connected_to_stack.reverse_each do |hash|
|
239
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
|
240
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_classes)
|
241
|
+
end
|
242
|
+
|
243
|
+
false
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def self.connected_to_stack # :nodoc:
|
248
|
+
if connected_to_stack = Thread.current.thread_variable_get(:ar_connected_to_stack)
|
249
|
+
connected_to_stack
|
250
|
+
else
|
251
|
+
connected_to_stack = Concurrent::Array.new
|
252
|
+
Thread.current.thread_variable_set(:ar_connected_to_stack, connected_to_stack)
|
253
|
+
connected_to_stack
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def self.connection_class=(b) # :nodoc:
|
258
|
+
@connection_class = b
|
259
|
+
end
|
260
|
+
|
261
|
+
def self.connection_class # :nodoc
|
262
|
+
@connection_class ||= false
|
263
|
+
end
|
264
|
+
|
265
|
+
def self.connection_class? # :nodoc:
|
266
|
+
self.connection_class
|
267
|
+
end
|
268
|
+
|
269
|
+
def self.connection_classes # :nodoc:
|
270
|
+
klass = self
|
271
|
+
|
272
|
+
until klass == Base
|
273
|
+
break if klass.connection_class?
|
274
|
+
klass = klass.superclass
|
275
|
+
end
|
276
|
+
|
277
|
+
klass
|
278
|
+
end
|
279
|
+
|
280
|
+
def self.allow_unsafe_raw_sql # :nodoc:
|
281
|
+
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 6.2")
|
282
|
+
end
|
283
|
+
|
284
|
+
def self.allow_unsafe_raw_sql=(value) # :nodoc:
|
285
|
+
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 6.2")
|
106
286
|
end
|
107
287
|
|
108
288
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
289
|
+
self.default_role = writing_role
|
290
|
+
self.default_shard = :default
|
291
|
+
|
292
|
+
def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
|
293
|
+
case action_on_strict_loading_violation
|
294
|
+
when :raise
|
295
|
+
message = "`#{owner}` is marked for strict_loading. The `#{reflection.klass}` association named `:#{reflection.name}` cannot be lazily loaded."
|
296
|
+
raise ActiveRecord::StrictLoadingViolationError.new(message)
|
297
|
+
when :log
|
298
|
+
name = "strict_loading_violation.active_record"
|
299
|
+
ActiveSupport::Notifications.instrument(name, owner: owner, reflection: reflection)
|
300
|
+
end
|
301
|
+
end
|
109
302
|
end
|
110
303
|
|
111
304
|
module ClassMethods
|
112
|
-
def allocate
|
113
|
-
define_attribute_methods
|
114
|
-
super
|
115
|
-
end
|
116
|
-
|
117
305
|
def initialize_find_by_cache # :nodoc:
|
118
|
-
|
306
|
+
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
|
119
307
|
end
|
120
308
|
|
121
309
|
def inherited(child_class) # :nodoc:
|
310
|
+
# initialize cache at class definition for thread safety
|
122
311
|
child_class.initialize_find_by_cache
|
312
|
+
unless child_class.base_class?
|
313
|
+
klass = self
|
314
|
+
until klass.base_class?
|
315
|
+
klass.initialize_find_by_cache
|
316
|
+
klass = klass.superclass
|
317
|
+
end
|
318
|
+
end
|
123
319
|
super
|
124
320
|
end
|
125
321
|
|
126
322
|
def find(*ids) # :nodoc:
|
127
323
|
# We don't have cache keys for this stuff yet
|
128
324
|
return super unless ids.length == 1
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
columns_hash.include?(inheritance_column) ||
|
136
|
-
ids.first.kind_of?(Array)
|
137
|
-
|
138
|
-
id = ids.first
|
139
|
-
if ActiveRecord::Base === id
|
140
|
-
id = id.id
|
141
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
142
|
-
You are passing an instance of ActiveRecord::Base to `find`.
|
143
|
-
Please pass the id of the object by calling `.id`
|
144
|
-
MSG
|
145
|
-
end
|
325
|
+
return super if block_given? || primary_key.nil? || scope_attributes?
|
326
|
+
|
327
|
+
id = ids.first
|
328
|
+
|
329
|
+
return super if StatementCache.unsupported_value?(id)
|
330
|
+
|
146
331
|
key = primary_key
|
147
332
|
|
148
|
-
|
149
|
-
|
150
|
-
where(key => params.bind).limit(1)
|
151
|
-
}
|
333
|
+
statement = cached_find_by_statement(key) { |params|
|
334
|
+
where(key => params.bind).limit(1)
|
152
335
|
}
|
153
|
-
|
154
|
-
|
155
|
-
raise
|
156
|
-
end
|
157
|
-
record
|
158
|
-
rescue RangeError
|
159
|
-
raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
|
336
|
+
|
337
|
+
statement.execute([id], connection).first ||
|
338
|
+
raise(RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id))
|
160
339
|
end
|
161
340
|
|
162
341
|
def find_by(*args) # :nodoc:
|
163
|
-
return super if
|
164
|
-
return super if default_scopes.any?
|
342
|
+
return super if scope_attributes?
|
165
343
|
|
166
344
|
hash = args.first
|
345
|
+
return super unless Hash === hash
|
167
346
|
|
168
|
-
|
169
|
-
|
170
|
-
|
347
|
+
hash = hash.each_with_object({}) do |(key, value), h|
|
348
|
+
key = key.to_s
|
349
|
+
key = attribute_aliases[key] || key
|
171
350
|
|
172
|
-
|
173
|
-
return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
|
351
|
+
return super if reflect_on_aggregation(key)
|
174
352
|
|
175
|
-
|
353
|
+
reflection = _reflect_on_association(key)
|
176
354
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
355
|
+
if !reflection
|
356
|
+
value = value.id if value.respond_to?(:id)
|
357
|
+
elsif reflection.belongs_to? && !reflection.polymorphic?
|
358
|
+
key = reflection.join_foreign_key
|
359
|
+
pkey = reflection.join_primary_key
|
360
|
+
value = value.public_send(pkey) if value.respond_to?(pkey)
|
361
|
+
end
|
362
|
+
|
363
|
+
if !columns_hash.key?(key) || StatementCache.unsupported_value?(value)
|
364
|
+
return super
|
365
|
+
end
|
366
|
+
|
367
|
+
h[key] = value
|
368
|
+
end
|
369
|
+
|
370
|
+
keys = hash.keys
|
371
|
+
statement = cached_find_by_statement(keys) { |params|
|
372
|
+
wheres = keys.index_with { params.bind }
|
373
|
+
where(wheres).limit(1)
|
185
374
|
}
|
375
|
+
|
186
376
|
begin
|
187
|
-
|
188
|
-
rescue TypeError
|
189
|
-
raise ActiveRecord::StatementInvalid
|
190
|
-
rescue RangeError
|
191
|
-
nil
|
377
|
+
statement.execute(hash.values, connection).first
|
378
|
+
rescue TypeError
|
379
|
+
raise ActiveRecord::StatementInvalid
|
192
380
|
end
|
193
381
|
end
|
194
382
|
|
195
383
|
def find_by!(*args) # :nodoc:
|
196
|
-
find_by(*args)
|
384
|
+
find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
|
197
385
|
end
|
198
386
|
|
199
387
|
def initialize_generated_modules # :nodoc:
|
200
388
|
generated_association_methods
|
201
389
|
end
|
202
390
|
|
203
|
-
def generated_association_methods
|
391
|
+
def generated_association_methods # :nodoc:
|
204
392
|
@generated_association_methods ||= begin
|
205
393
|
mod = const_set(:GeneratedAssociationMethods, Module.new)
|
394
|
+
private_constant :GeneratedAssociationMethods
|
206
395
|
include mod
|
396
|
+
|
207
397
|
mod
|
208
398
|
end
|
209
399
|
end
|
210
400
|
|
401
|
+
# Returns columns which shouldn't be exposed while calling +#inspect+.
|
402
|
+
def filter_attributes
|
403
|
+
if defined?(@filter_attributes)
|
404
|
+
@filter_attributes
|
405
|
+
else
|
406
|
+
superclass.filter_attributes
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
# Specifies columns which shouldn't be exposed while calling +#inspect+.
|
411
|
+
def filter_attributes=(filter_attributes)
|
412
|
+
@inspection_filter = nil
|
413
|
+
@filter_attributes = filter_attributes
|
414
|
+
end
|
415
|
+
|
416
|
+
def inspection_filter # :nodoc:
|
417
|
+
if defined?(@filter_attributes)
|
418
|
+
@inspection_filter ||= begin
|
419
|
+
mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
|
420
|
+
ActiveSupport::ParameterFilter.new(@filter_attributes, mask: mask)
|
421
|
+
end
|
422
|
+
else
|
423
|
+
superclass.inspection_filter
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
211
427
|
# Returns a string like 'Post(id:integer, title:string, body:text)'
|
212
|
-
def inspect
|
428
|
+
def inspect # :nodoc:
|
213
429
|
if self == Base
|
214
430
|
super
|
215
431
|
elsif abstract_class?
|
@@ -217,48 +433,63 @@ module ActiveRecord
|
|
217
433
|
elsif !connected?
|
218
434
|
"#{super} (call '#{super}.connection' to establish a connection)"
|
219
435
|
elsif table_exists?
|
220
|
-
attr_list =
|
436
|
+
attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
|
221
437
|
"#{super}(#{attr_list})"
|
222
438
|
else
|
223
439
|
"#{super}(Table doesn't exist)"
|
224
440
|
end
|
225
441
|
end
|
226
442
|
|
227
|
-
# Overwrite the default class equality method to provide support for
|
228
|
-
def ===(object)
|
443
|
+
# Overwrite the default class equality method to provide support for decorated models.
|
444
|
+
def ===(object) # :nodoc:
|
229
445
|
object.is_a?(self)
|
230
446
|
end
|
231
447
|
|
232
448
|
# Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
|
233
449
|
#
|
234
450
|
# class Post < ActiveRecord::Base
|
235
|
-
# scope :published_and_commented, -> { published.and(
|
451
|
+
# scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
|
236
452
|
# end
|
237
453
|
def arel_table # :nodoc:
|
238
|
-
@arel_table ||= Arel::Table.new(table_name,
|
454
|
+
@arel_table ||= Arel::Table.new(table_name, klass: self)
|
239
455
|
end
|
240
456
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
457
|
+
def arel_attribute(name, table = arel_table) # :nodoc:
|
458
|
+
table[name]
|
459
|
+
end
|
460
|
+
deprecate :arel_attribute
|
461
|
+
|
462
|
+
def predicate_builder # :nodoc:
|
463
|
+
@predicate_builder ||= PredicateBuilder.new(table_metadata)
|
464
|
+
end
|
465
|
+
|
466
|
+
def type_caster # :nodoc:
|
467
|
+
TypeCaster::Map.new(self)
|
468
|
+
end
|
469
|
+
|
470
|
+
def _internal? # :nodoc:
|
471
|
+
false
|
472
|
+
end
|
473
|
+
|
474
|
+
def cached_find_by_statement(key, &block) # :nodoc:
|
475
|
+
cache = @find_by_statement_cache[connection.prepared_statements]
|
476
|
+
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
249
477
|
end
|
250
478
|
|
251
479
|
private
|
480
|
+
def relation
|
481
|
+
relation = Relation.create(self)
|
252
482
|
|
253
|
-
|
254
|
-
|
483
|
+
if finder_needs_type_condition? && !ignore_default_scope?
|
484
|
+
relation.where!(type_condition)
|
485
|
+
else
|
486
|
+
relation
|
487
|
+
end
|
488
|
+
end
|
255
489
|
|
256
|
-
|
257
|
-
|
258
|
-
else
|
259
|
-
relation
|
490
|
+
def table_metadata
|
491
|
+
TableMetadata.new(self, arel_table)
|
260
492
|
end
|
261
|
-
end
|
262
493
|
end
|
263
494
|
|
264
495
|
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
@@ -269,16 +500,14 @@ module ActiveRecord
|
|
269
500
|
# ==== Example:
|
270
501
|
# # Instantiates a single new object
|
271
502
|
# User.new(first_name: 'Jamie')
|
272
|
-
def initialize(attributes = nil
|
273
|
-
@
|
274
|
-
self.class.
|
503
|
+
def initialize(attributes = nil)
|
504
|
+
@new_record = true
|
505
|
+
@attributes = self.class._default_attributes.deep_dup
|
275
506
|
|
276
507
|
init_internals
|
277
508
|
initialize_internals_callback
|
278
509
|
|
279
|
-
|
280
|
-
# Remove it when we drop support to this gem.
|
281
|
-
init_attributes(attributes, options) if attributes
|
510
|
+
assign_attributes(attributes) if attributes
|
282
511
|
|
283
512
|
yield self if block_given?
|
284
513
|
_run_initialize_callbacks
|
@@ -286,7 +515,7 @@ module ActiveRecord
|
|
286
515
|
|
287
516
|
# Initialize an empty model object from +coder+. +coder+ should be
|
288
517
|
# the result of previously encoding an Active Record model, using
|
289
|
-
#
|
518
|
+
# #encode_with.
|
290
519
|
#
|
291
520
|
# class Post < ActiveRecord::Base
|
292
521
|
# end
|
@@ -298,15 +527,23 @@ module ActiveRecord
|
|
298
527
|
# post = Post.allocate
|
299
528
|
# post.init_with(coder)
|
300
529
|
# post.title # => 'hello world'
|
301
|
-
def init_with(coder)
|
530
|
+
def init_with(coder, &block)
|
302
531
|
coder = LegacyYamlAdapter.convert(self.class, coder)
|
303
|
-
|
532
|
+
attributes = self.class.yaml_encoder.decode(coder)
|
533
|
+
init_with_attributes(attributes, coder["new_record"], &block)
|
534
|
+
end
|
304
535
|
|
305
|
-
|
536
|
+
##
|
537
|
+
# Initialize an empty model object from +attributes+.
|
538
|
+
# +attributes+ should be an attributes object, and unlike the
|
539
|
+
# `initialize` method, no assignment calls are made per attribute.
|
540
|
+
def init_with_attributes(attributes, new_record = false) # :nodoc:
|
541
|
+
@new_record = new_record
|
542
|
+
@attributes = attributes
|
306
543
|
|
307
|
-
|
544
|
+
init_internals
|
308
545
|
|
309
|
-
self
|
546
|
+
yield self if block_given?
|
310
547
|
|
311
548
|
_run_find_callbacks
|
312
549
|
_run_initialize_callbacks
|
@@ -342,23 +579,22 @@ module ActiveRecord
|
|
342
579
|
|
343
580
|
##
|
344
581
|
def initialize_dup(other) # :nodoc:
|
345
|
-
@attributes = @attributes.
|
346
|
-
@attributes.reset(
|
582
|
+
@attributes = @attributes.deep_dup
|
583
|
+
@attributes.reset(@primary_key)
|
347
584
|
|
348
585
|
_run_initialize_callbacks
|
349
586
|
|
350
|
-
@
|
351
|
-
@
|
352
|
-
|
353
|
-
@
|
354
|
-
@destroyed = false
|
587
|
+
@new_record = true
|
588
|
+
@previously_new_record = false
|
589
|
+
@destroyed = false
|
590
|
+
@_start_transaction_state = nil
|
355
591
|
|
356
592
|
super
|
357
593
|
end
|
358
594
|
|
359
595
|
# Populate +coder+ with attributes about this record that should be
|
360
596
|
# serialized. The structure of +coder+ defined in this method is
|
361
|
-
# guaranteed to match the structure of +coder+ passed to the
|
597
|
+
# guaranteed to match the structure of +coder+ passed to the #init_with
|
362
598
|
# method.
|
363
599
|
#
|
364
600
|
# Example:
|
@@ -369,11 +605,9 @@ module ActiveRecord
|
|
369
605
|
# Post.new.encode_with(coder)
|
370
606
|
# coder # => {"attributes" => {"id" => nil, ... }}
|
371
607
|
def encode_with(coder)
|
372
|
-
|
373
|
-
coder[
|
374
|
-
coder[
|
375
|
-
coder['new_record'] = new_record?
|
376
|
-
coder['active_record_yaml_version'] = 0
|
608
|
+
self.class.yaml_encoder.encode(@attributes, coder)
|
609
|
+
coder["new_record"] = new_record?
|
610
|
+
coder["active_record_yaml_version"] = 2
|
377
611
|
end
|
378
612
|
|
379
613
|
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
@@ -397,7 +631,7 @@ module ActiveRecord
|
|
397
631
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
398
632
|
def hash
|
399
633
|
if id
|
400
|
-
id.hash
|
634
|
+
self.class.hash ^ id.hash
|
401
635
|
else
|
402
636
|
super
|
403
637
|
end
|
@@ -419,18 +653,41 @@ module ActiveRecord
|
|
419
653
|
# Allows sort on objects
|
420
654
|
def <=>(other_object)
|
421
655
|
if other_object.is_a?(self.class)
|
422
|
-
|
656
|
+
to_key <=> other_object.to_key
|
423
657
|
else
|
424
658
|
super
|
425
659
|
end
|
426
660
|
end
|
427
661
|
|
428
|
-
|
429
|
-
|
662
|
+
def present? # :nodoc:
|
663
|
+
true
|
664
|
+
end
|
665
|
+
|
666
|
+
def blank? # :nodoc:
|
667
|
+
false
|
668
|
+
end
|
669
|
+
|
670
|
+
# Returns +true+ if the record is read only.
|
430
671
|
def readonly?
|
431
672
|
@readonly
|
432
673
|
end
|
433
674
|
|
675
|
+
# Returns +true+ if the record is in strict_loading mode.
|
676
|
+
def strict_loading?
|
677
|
+
@strict_loading
|
678
|
+
end
|
679
|
+
|
680
|
+
# Sets the record to strict_loading mode. This will raise an error
|
681
|
+
# if the record tries to lazily load an association.
|
682
|
+
#
|
683
|
+
# user = User.first
|
684
|
+
# user.strict_loading!
|
685
|
+
# user.comments.to_a
|
686
|
+
# => ActiveRecord::StrictLoadingViolationError
|
687
|
+
def strict_loading!
|
688
|
+
@strict_loading = true
|
689
|
+
end
|
690
|
+
|
434
691
|
# Marks this record as read only.
|
435
692
|
def readonly!
|
436
693
|
@readonly = true
|
@@ -445,135 +702,95 @@ module ActiveRecord
|
|
445
702
|
# We check defined?(@attributes) not to issue warnings if the object is
|
446
703
|
# allocated but not initialized.
|
447
704
|
inspection = if defined?(@attributes) && @attributes
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
705
|
+
self.class.attribute_names.collect do |name|
|
706
|
+
if _has_attribute?(name)
|
707
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
708
|
+
end
|
709
|
+
end.compact.join(", ")
|
710
|
+
else
|
711
|
+
"not initialized"
|
712
|
+
end
|
713
|
+
|
456
714
|
"#<#{self.class} #{inspection}>"
|
457
715
|
end
|
458
716
|
|
459
|
-
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from
|
717
|
+
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from <tt>pp record</tt>
|
460
718
|
# when pp is required.
|
461
719
|
def pretty_print(pp)
|
462
720
|
return super if custom_inspect_method_defined?
|
463
721
|
pp.object_address_group(self) do
|
464
722
|
if defined?(@attributes) && @attributes
|
465
|
-
|
466
|
-
pp.seplist(
|
467
|
-
|
468
|
-
pp.breakable ' '
|
723
|
+
attr_names = self.class.attribute_names.select { |name| _has_attribute?(name) }
|
724
|
+
pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
|
725
|
+
pp.breakable " "
|
469
726
|
pp.group(1) do
|
470
|
-
pp.text
|
471
|
-
pp.text
|
727
|
+
pp.text attr_name
|
728
|
+
pp.text ":"
|
472
729
|
pp.breakable
|
473
|
-
|
730
|
+
value = _read_attribute(attr_name)
|
731
|
+
value = inspection_filter.filter_param(attr_name, value) unless value.nil?
|
732
|
+
pp.pp value
|
474
733
|
end
|
475
734
|
end
|
476
735
|
else
|
477
|
-
pp.breakable
|
478
|
-
pp.text
|
736
|
+
pp.breakable " "
|
737
|
+
pp.text "not initialized"
|
479
738
|
end
|
480
739
|
end
|
481
740
|
end
|
482
741
|
|
483
742
|
# Returns a hash of the given methods with their names as keys and returned values as values.
|
484
743
|
def slice(*methods)
|
485
|
-
|
744
|
+
methods.flatten.index_with { |method| public_send(method) }.with_indifferent_access
|
486
745
|
end
|
487
746
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
@transaction_state = state
|
747
|
+
# Returns an array of the values returned by the given methods.
|
748
|
+
def values_at(*methods)
|
749
|
+
methods.flatten.map! { |method| public_send(method) }
|
492
750
|
end
|
493
751
|
|
494
|
-
|
495
|
-
|
496
|
-
|
752
|
+
private
|
753
|
+
# +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
|
754
|
+
# the array, and then rescues from the possible +NoMethodError+. If those elements are
|
755
|
+
# +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
|
756
|
+
# which significantly impacts upon performance.
|
757
|
+
#
|
758
|
+
# So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
|
759
|
+
#
|
760
|
+
# See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
|
761
|
+
def to_ary
|
762
|
+
nil
|
763
|
+
end
|
497
764
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
# as appropriate.
|
511
|
-
#
|
512
|
-
# Since ActiveRecord objects can be inside multiple transactions, this
|
513
|
-
# method recursively goes through the parent of the TransactionState and
|
514
|
-
# checks if the ActiveRecord object reflects the state of the object.
|
515
|
-
def sync_with_transaction_state
|
516
|
-
update_attributes_from_transaction_state(@transaction_state, 0)
|
517
|
-
end
|
765
|
+
def init_internals
|
766
|
+
@primary_key = self.class.primary_key
|
767
|
+
@readonly = false
|
768
|
+
@previously_new_record = false
|
769
|
+
@destroyed = false
|
770
|
+
@marked_for_destruction = false
|
771
|
+
@destroyed_by_association = nil
|
772
|
+
@_start_transaction_state = nil
|
773
|
+
@strict_loading = self.class.strict_loading_by_default
|
774
|
+
|
775
|
+
self.class.define_attribute_methods
|
776
|
+
end
|
518
777
|
|
519
|
-
|
520
|
-
|
778
|
+
def initialize_internals_callback
|
779
|
+
end
|
521
780
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
clear_transaction_record_state
|
526
|
-
@reflects_state[depth] = true
|
527
|
-
end
|
781
|
+
def custom_inspect_method_defined?
|
782
|
+
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
783
|
+
end
|
528
784
|
|
529
|
-
|
530
|
-
|
785
|
+
class InspectionMask < DelegateClass(::String)
|
786
|
+
def pretty_print(pp)
|
787
|
+
pp.text __getobj__
|
531
788
|
end
|
532
789
|
end
|
533
|
-
|
534
|
-
|
535
|
-
# Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements
|
536
|
-
# of the array, and then rescues from the possible NoMethodError. If those elements are
|
537
|
-
# ActiveRecord::Base's, then this triggers the various method_missing's that we have,
|
538
|
-
# which significantly impacts upon performance.
|
539
|
-
#
|
540
|
-
# So we can avoid the method_missing hit by explicitly defining #to_ary as nil here.
|
541
|
-
#
|
542
|
-
# See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
|
543
|
-
def to_ary # :nodoc:
|
544
|
-
nil
|
545
|
-
end
|
546
|
-
|
547
|
-
def init_internals
|
548
|
-
@aggregation_cache = {}
|
549
|
-
@association_cache = {}
|
550
|
-
@readonly = false
|
551
|
-
@destroyed = false
|
552
|
-
@marked_for_destruction = false
|
553
|
-
@destroyed_by_association = nil
|
554
|
-
@new_record = true
|
555
|
-
@txn = nil
|
556
|
-
@_start_transaction_state = {}
|
557
|
-
@transaction_state = nil
|
558
|
-
end
|
559
|
-
|
560
|
-
def initialize_internals_callback
|
561
|
-
end
|
562
|
-
|
563
|
-
# This method is needed to make protected_attributes gem easier to hook.
|
564
|
-
# Remove it when we drop support to this gem.
|
565
|
-
def init_attributes(attributes, options)
|
566
|
-
assign_attributes(attributes)
|
567
|
-
end
|
790
|
+
private_constant :InspectionMask
|
568
791
|
|
569
|
-
|
570
|
-
|
571
|
-
@attributes = @attributes.dup
|
792
|
+
def inspection_filter
|
793
|
+
self.class.inspection_filter
|
572
794
|
end
|
573
|
-
end
|
574
|
-
|
575
|
-
def custom_inspect_method_defined?
|
576
|
-
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
577
|
-
end
|
578
795
|
end
|
579
796
|
end
|