activerecord 5.0.7.2 → 6.0.3.4
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 +708 -2040
- data/MIT-LICENSE +3 -1
- data/README.rdoc +9 -7
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record.rb +37 -22
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +18 -14
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/associations/alias_tracker.rb +24 -34
- data/lib/active_record/associations/association.rb +114 -55
- data/lib/active_record/associations/association_scope.rb +94 -94
- data/lib/active_record/associations/belongs_to_association.rb +58 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +18 -25
- data/lib/active_record/associations/builder/belongs_to.rb +43 -54
- data/lib/active_record/associations/builder/collection_association.rb +7 -18
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
- data/lib/active_record/associations/builder/has_many.rb +4 -0
- data/lib/active_record/associations/builder/has_one.rb +37 -1
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +86 -254
- data/lib/active_record/associations/collection_proxy.rb +158 -122
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -30
- data/lib/active_record/associations/has_many_through_association.rb +58 -44
- data/lib/active_record/associations/has_one_association.rb +59 -54
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +143 -176
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -87
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/preloader.rb +90 -103
- data/lib/active_record/associations/preloader/association.rb +86 -100
- data/lib/active_record/associations/preloader/through_association.rb +77 -76
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +26 -14
- data/lib/active_record/attribute_assignment.rb +54 -61
- data/lib/active_record/attribute_decorators.rb +38 -17
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +85 -92
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +20 -49
- data/lib/active_record/attribute_methods/serialization.rb +29 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
- data/lib/active_record/attribute_methods/write.rb +34 -33
- data/lib/active_record/attributes.rb +38 -25
- data/lib/active_record/autosave_association.rb +54 -35
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +64 -35
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -12
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +552 -323
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +228 -147
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
- data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +396 -562
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
- 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 +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -31
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +8 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
- data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +259 -266
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +143 -40
- data/lib/active_record/core.rb +201 -163
- data/lib/active_record/counter_cache.rb +60 -28
- 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 +78 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -87
- data/lib/active_record/enum.rb +60 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -4
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +13 -8
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +194 -504
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +150 -99
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +16 -19
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +77 -87
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +48 -29
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +369 -302
- data/lib/active_record/migration/command_recorder.rb +134 -100
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/model_schema.rb +131 -127
- data/lib/active_record/nested_attributes.rb +213 -202
- data/lib/active_record/no_touching.rb +12 -3
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +446 -77
- data/lib/active_record/query_cache.rb +13 -12
- data/lib/active_record/querying.rb +37 -24
- data/lib/active_record/railtie.rb +128 -36
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +312 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +214 -252
- data/lib/active_record/relation.rb +440 -318
- data/lib/active_record/relation/batches.rb +98 -52
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/calculations.rb +212 -173
- data/lib/active_record/relation/delegation.rb +72 -69
- data/lib/active_record/relation/finder_methods.rb +207 -247
- data/lib/active_record/relation/from_clause.rb +6 -8
- data/lib/active_record/relation/merger.rb +78 -62
- data/lib/active_record/relation/predicate_builder.rb +83 -105
- data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +476 -334
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +111 -96
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/result.rb +69 -40
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +83 -99
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +71 -69
- data/lib/active_record/schema_migration.rb +16 -6
- data/lib/active_record/scoping.rb +20 -20
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +47 -27
- data/lib/active_record/secure_token.rb +4 -2
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +63 -28
- data/lib/active_record/store.rb +121 -41
- data/lib/active_record/suppressor.rb +6 -3
- data/lib/active_record/table_metadata.rb +39 -18
- data/lib/active_record/tasks/database_tasks.rb +271 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
- data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +225 -0
- data/lib/active_record/timestamp.rb +70 -36
- data/lib/active_record/touch_later.rb +8 -6
- data/lib/active_record/transactions.rb +141 -157
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +23 -18
- data/lib/active_record/type/adapter_specific_registry.rb +44 -48
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +16 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +2 -1
- data/lib/active_record/type/type_map.rb +14 -17
- data/lib/active_record/type/unsigned_integer.rb +16 -0
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/type_caster/connection.rb +17 -12
- data/lib/active_record/type_caster/map.rb +5 -4
- data/lib/active_record/validations.rb +7 -5
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +4 -3
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +29 -42
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +62 -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 +256 -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 +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -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 +26 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +17 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +137 -52
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -20
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/attribute_set/builder.rb +0 -132
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module Query
|
@@ -14,8 +16,7 @@ module ActiveRecord
|
|
14
16
|
when true then true
|
15
17
|
when false, nil then false
|
16
18
|
else
|
17
|
-
|
18
|
-
if column.nil?
|
19
|
+
if !type_for_attribute(attr_name) { false }
|
19
20
|
if Numeric === value || value !~ /[^0-9]/
|
20
21
|
!value.to_i.zero?
|
21
22
|
else
|
@@ -31,7 +32,7 @@ module ActiveRecord
|
|
31
32
|
end
|
32
33
|
|
33
34
|
private
|
34
|
-
#
|
35
|
+
# Dispatch target for <tt>*?</tt> attribute methods.
|
35
36
|
def attribute?(attribute_name)
|
36
37
|
query_attribute(attribute_name)
|
37
38
|
end
|
@@ -1,47 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module Read
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
6
|
-
module ClassMethods
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
# 'my_column(omg)'. So to work around this we first define with
|
19
|
-
# the __temp__ identifier, and then use alias method to rename
|
20
|
-
# it to what we want.
|
21
|
-
#
|
22
|
-
# We are also defining a constant to hold the frozen string of
|
23
|
-
# the attribute name. Using a constant means that we do not have
|
24
|
-
# to allocate an object on each call to the attribute method.
|
25
|
-
# Making it frozen means that it doesn't get duped when used to
|
26
|
-
# key the @attributes in read_attribute.
|
27
|
-
def define_method_attribute(name)
|
28
|
-
safe_name = name.unpack('h*'.freeze).first
|
29
|
-
temp_method = "__temp__#{safe_name}"
|
30
|
-
|
31
|
-
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
|
32
|
-
|
33
|
-
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
34
|
-
def #{temp_method}
|
35
|
-
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
36
|
-
_read_attribute(name) { |n| missing_attribute(n, caller) }
|
8
|
+
module ClassMethods # :nodoc:
|
9
|
+
private
|
10
|
+
def define_method_attribute(name)
|
11
|
+
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
12
|
+
generated_attribute_methods, name
|
13
|
+
) do |temp_method_name, attr_name_expr|
|
14
|
+
generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
15
|
+
def #{temp_method_name}
|
16
|
+
name = #{attr_name_expr}
|
17
|
+
_read_attribute(name) { |n| missing_attribute(n, caller) }
|
18
|
+
end
|
19
|
+
RUBY
|
37
20
|
end
|
38
|
-
STR
|
39
|
-
|
40
|
-
generated_attribute_methods.module_eval do
|
41
|
-
alias_method name, temp_method
|
42
|
-
undef_method temp_method
|
43
21
|
end
|
44
|
-
end
|
45
22
|
end
|
46
23
|
|
47
24
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after
|
@@ -49,27 +26,21 @@ module ActiveRecord
|
|
49
26
|
# to a date object, like Date.new(2004, 12, 12)).
|
50
27
|
def read_attribute(attr_name, &block)
|
51
28
|
name = attr_name.to_s
|
52
|
-
name = self.class.
|
29
|
+
name = self.class.attribute_aliases[name] || name
|
30
|
+
|
31
|
+
name = @primary_key if name == "id" && @primary_key
|
53
32
|
_read_attribute(name, &block)
|
54
33
|
end
|
55
34
|
|
56
35
|
# This method exists to avoid the expensive primary_key check internally, without
|
57
36
|
# breaking compatibility with the read_attribute API
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
def _read_attribute(attr_name, &block) # :nodoc
|
62
|
-
@attributes.fetch_value(attr_name.to_s, &block)
|
63
|
-
end
|
64
|
-
else
|
65
|
-
def _read_attribute(attr_name) # :nodoc:
|
66
|
-
@attributes.fetch_value(attr_name.to_s) { |n| yield n if block_given? }
|
67
|
-
end
|
37
|
+
def _read_attribute(attr_name, &block) # :nodoc
|
38
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
39
|
+
@attributes.fetch_value(attr_name.to_s, &block)
|
68
40
|
end
|
69
41
|
|
70
42
|
alias :attribute :_read_attribute
|
71
43
|
private :attribute
|
72
|
-
|
73
44
|
end
|
74
45
|
end
|
75
46
|
end
|
@@ -1,8 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module Serialization
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
8
|
+
class ColumnNotSerializableError < StandardError
|
9
|
+
def initialize(name, type)
|
10
|
+
super <<~EOS
|
11
|
+
Column `#{name}` of type #{type.class} does not support `serialize` feature.
|
12
|
+
Usually it means that you are trying to use `serialize`
|
13
|
+
on a column that already implements serialization natively.
|
14
|
+
EOS
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
6
18
|
module ClassMethods
|
7
19
|
# If you have an attribute that needs to be saved to the database as an
|
8
20
|
# object, and retrieved as the same object, then specify the name of that
|
@@ -26,7 +38,7 @@ module ActiveRecord
|
|
26
38
|
# ==== Parameters
|
27
39
|
#
|
28
40
|
# * +attr_name+ - The field name that should be serialized.
|
29
|
-
# * +class_name_or_coder+ - Optional, a coder object, which responds to
|
41
|
+
# * +class_name_or_coder+ - Optional, a coder object, which responds to +.load+ and +.dump+
|
30
42
|
# or a class name that the object type should be equal to.
|
31
43
|
#
|
32
44
|
# ==== Example
|
@@ -50,17 +62,27 @@ module ActiveRecord
|
|
50
62
|
# to ensure special objects (e.g. Active Record models) are dumped correctly
|
51
63
|
# using the #as_json hook.
|
52
64
|
coder = if class_name_or_coder == ::JSON
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
65
|
+
Coders::JSON
|
66
|
+
elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
|
67
|
+
class_name_or_coder
|
68
|
+
else
|
69
|
+
Coders::YAMLColumn.new(attr_name, class_name_or_coder)
|
70
|
+
end
|
59
71
|
|
60
72
|
decorate_attribute_type(attr_name, :serialize) do |type|
|
73
|
+
if type_incompatible_with_serialize?(type, class_name_or_coder)
|
74
|
+
raise ColumnNotSerializableError.new(attr_name, type)
|
75
|
+
end
|
76
|
+
|
61
77
|
Type::Serialized.new(type, coder)
|
62
78
|
end
|
63
79
|
end
|
80
|
+
|
81
|
+
private
|
82
|
+
def type_incompatible_with_serialize?(type, class_name)
|
83
|
+
type.is_a?(ActiveRecord::Type::Json) && class_name == ::JSON ||
|
84
|
+
type.respond_to?(:type_cast_array, true) && class_name == ::Array
|
85
|
+
end
|
64
86
|
end
|
65
87
|
end
|
66
88
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module AttributeMethods
|
@@ -25,91 +25,64 @@ module ActiveRecord
|
|
25
25
|
end
|
26
26
|
|
27
27
|
private
|
28
|
+
def convert_time_to_time_zone(value)
|
29
|
+
return if value.nil?
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
else
|
37
|
-
map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
|
31
|
+
if value.acts_like?(:time)
|
32
|
+
value.in_time_zone
|
33
|
+
elsif value.is_a?(::Float)
|
34
|
+
value
|
35
|
+
else
|
36
|
+
map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
|
37
|
+
end
|
38
38
|
end
|
39
|
-
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def set_time_zone_without_conversion(value)
|
41
|
+
::Time.zone.local_to_utc(value).try(:in_time_zone) if value
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
44
|
+
def map_avoiding_infinite_recursion(value)
|
45
|
+
map(value) do |v|
|
46
|
+
if value.equal?(v)
|
47
|
+
nil
|
48
|
+
else
|
49
|
+
yield(v)
|
50
|
+
end
|
51
51
|
end
|
52
52
|
end
|
53
|
-
end
|
54
53
|
end
|
55
54
|
|
56
55
|
extend ActiveSupport::Concern
|
57
56
|
|
58
57
|
included do
|
59
|
-
mattr_accessor :time_zone_aware_attributes, instance_writer: false
|
60
|
-
self.time_zone_aware_attributes = false
|
61
|
-
|
62
|
-
class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false
|
63
|
-
self.skip_time_zone_conversion_for_attributes = []
|
58
|
+
mattr_accessor :time_zone_aware_attributes, instance_writer: false, default: false
|
64
59
|
|
65
|
-
class_attribute :
|
66
|
-
|
60
|
+
class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false, default: []
|
61
|
+
class_attribute :time_zone_aware_types, instance_writer: false, default: [ :datetime, :time ]
|
67
62
|
end
|
68
63
|
|
69
|
-
module ClassMethods
|
64
|
+
module ClassMethods # :nodoc:
|
70
65
|
private
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
66
|
+
def inherited(subclass)
|
67
|
+
super
|
68
|
+
# We need to apply this decorator here, rather than on module inclusion. The closure
|
69
|
+
# created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
|
70
|
+
# sub class being decorated. As such, changes to `time_zone_aware_attributes`, or
|
71
|
+
# `skip_time_zone_conversion_for_attributes` would not be picked up.
|
72
|
+
subclass.class_eval do
|
73
|
+
matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) }
|
74
|
+
decorate_matching_attribute_types(matcher, "_time_zone_conversion") do |type|
|
75
|
+
TimeZoneConverter.new(type)
|
76
|
+
end
|
81
77
|
end
|
82
78
|
end
|
83
|
-
super
|
84
|
-
end
|
85
|
-
|
86
|
-
def create_time_zone_conversion_attribute?(name, cast_type)
|
87
|
-
enabled_for_column = time_zone_aware_attributes &&
|
88
|
-
!self.skip_time_zone_conversion_for_attributes.include?(name.to_sym)
|
89
|
-
result = enabled_for_column &&
|
90
|
-
time_zone_aware_types.include?(cast_type.type)
|
91
79
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
time_zone_aware_types.include?(:not_explicitly_configured)
|
96
|
-
ActiveSupport::Deprecation.warn(<<-MESSAGE.strip_heredoc)
|
97
|
-
Time columns will become time zone aware in Rails 5.1. This
|
98
|
-
still causes `String`s to be parsed as if they were in `Time.zone`,
|
99
|
-
and `Time`s to be converted to `Time.zone`.
|
80
|
+
def create_time_zone_conversion_attribute?(name, cast_type)
|
81
|
+
enabled_for_column = time_zone_aware_attributes &&
|
82
|
+
!skip_time_zone_conversion_for_attributes.include?(name.to_sym)
|
100
83
|
|
101
|
-
|
102
|
-
|
103
|
-
config.active_record.time_zone_aware_types = [:datetime]
|
104
|
-
|
105
|
-
To use the new behavior, add the following:
|
106
|
-
|
107
|
-
config.active_record.time_zone_aware_types = [:datetime, :time]
|
108
|
-
MESSAGE
|
84
|
+
enabled_for_column && time_zone_aware_types.include?(cast_type.type)
|
109
85
|
end
|
110
|
-
|
111
|
-
result
|
112
|
-
end
|
113
86
|
end
|
114
87
|
end
|
115
88
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module Write
|
@@ -7,53 +9,52 @@ module ActiveRecord
|
|
7
9
|
attribute_method_suffix "="
|
8
10
|
end
|
9
11
|
|
10
|
-
module ClassMethods
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
module ClassMethods # :nodoc:
|
13
|
+
private
|
14
|
+
def define_method_attribute=(name)
|
15
|
+
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
16
|
+
generated_attribute_methods, name, writer: true,
|
17
|
+
) do |temp_method_name, attr_name_expr|
|
18
|
+
generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
19
|
+
def #{temp_method_name}(value)
|
20
|
+
name = #{attr_name_expr}
|
21
|
+
_write_attribute(name, value)
|
22
|
+
end
|
23
|
+
RUBY
|
21
24
|
end
|
22
|
-
|
23
|
-
undef_method :__temp__#{safe_name}=
|
24
|
-
STR
|
25
|
-
end
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
28
|
# Updates the attribute identified by <tt>attr_name</tt> with the
|
29
29
|
# specified +value+. Empty strings for Integer and Float columns are
|
30
30
|
# turned into +nil+.
|
31
31
|
def write_attribute(attr_name, value)
|
32
|
-
|
33
|
-
|
32
|
+
name = attr_name.to_s
|
33
|
+
name = self.class.attribute_aliases[name] || name
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
name = @primary_key if name == "id" && @primary_key
|
36
|
+
_write_attribute(name, value)
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
#
|
41
|
-
def
|
42
|
-
|
39
|
+
# This method exists to avoid the expensive primary_key check internally, without
|
40
|
+
# breaking compatibility with the write_attribute API
|
41
|
+
def _write_attribute(attr_name, value) # :nodoc:
|
42
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
43
|
+
@attributes.write_from_user(attr_name.to_s, value)
|
44
|
+
value
|
43
45
|
end
|
44
46
|
|
45
|
-
|
46
|
-
attr_name
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@attributes.write_from_user(attr_name, value)
|
51
|
-
else
|
52
|
-
@attributes.write_cast_value(attr_name, value)
|
47
|
+
private
|
48
|
+
def write_attribute_without_type_cast(attr_name, value)
|
49
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
50
|
+
@attributes.write_cast_value(attr_name.to_s, value)
|
51
|
+
value
|
53
52
|
end
|
54
53
|
|
55
|
-
|
56
|
-
|
54
|
+
# Dispatch target for <tt>*=</tt> attribute methods.
|
55
|
+
def attribute=(attribute_name, value)
|
56
|
+
_write_attribute(attribute_name, value)
|
57
|
+
end
|
57
58
|
end
|
58
59
|
end
|
59
60
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_model/attribute/user_provided_default"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
# See ActiveRecord::Attributes::ClassMethods for documentation
|
@@ -6,8 +8,7 @@ module ActiveRecord
|
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
|
8
10
|
included do
|
9
|
-
class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false # :internal:
|
10
|
-
self.attributes_to_define_after_schema_loads = {}
|
11
|
+
class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false, default: {} # :internal:
|
11
12
|
end
|
12
13
|
|
13
14
|
module ClassMethods
|
@@ -40,6 +41,9 @@ module ActiveRecord
|
|
40
41
|
# +range+ (PostgreSQL only) specifies that the type should be a range (see the
|
41
42
|
# examples below).
|
42
43
|
#
|
44
|
+
# When using a symbol for +cast_type+, extra options are forwarded to the
|
45
|
+
# constructor of the type object.
|
46
|
+
#
|
43
47
|
# ==== Examples
|
44
48
|
#
|
45
49
|
# The type detected by Active Record can be overridden.
|
@@ -56,7 +60,7 @@ module ActiveRecord
|
|
56
60
|
# store_listing = StoreListing.new(price_in_cents: '10.1')
|
57
61
|
#
|
58
62
|
# # before
|
59
|
-
# store_listing.price_in_cents # => BigDecimal
|
63
|
+
# store_listing.price_in_cents # => BigDecimal(10.1)
|
60
64
|
#
|
61
65
|
# class StoreListing < ActiveRecord::Base
|
62
66
|
# attribute :price_in_cents, :integer
|
@@ -111,12 +115,22 @@ module ActiveRecord
|
|
111
115
|
# my_float_range: 1.0..3.5
|
112
116
|
# }
|
113
117
|
#
|
118
|
+
# Passing options to the type constructor
|
119
|
+
#
|
120
|
+
# # app/models/my_model.rb
|
121
|
+
# class MyModel < ActiveRecord::Base
|
122
|
+
# attribute :small_int, :integer, limit: 2
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# MyModel.create(small_int: 65537)
|
126
|
+
# # => Error: 65537 is out of range for the limit of two bytes
|
127
|
+
#
|
114
128
|
# ==== Creating Custom Types
|
115
129
|
#
|
116
130
|
# Users may also define their own custom types, as long as they respond
|
117
131
|
# to the methods defined on the value type. The method +deserialize+ or
|
118
132
|
# +cast+ will be called on your type object, with raw input from the
|
119
|
-
# database or from your controllers. See
|
133
|
+
# database or from your controllers. See ActiveModel::Type::Value for the
|
120
134
|
# expected API. It is recommended that your type objects inherit from an
|
121
135
|
# existing type, or from ActiveRecord::Type::Value
|
122
136
|
#
|
@@ -143,7 +157,7 @@ module ActiveRecord
|
|
143
157
|
# store_listing.price_in_cents # => 1000
|
144
158
|
#
|
145
159
|
# For more details on creating custom types, see the documentation for
|
146
|
-
#
|
160
|
+
# ActiveModel::Type::Value. For more details on registering your types
|
147
161
|
# to be referenced by a symbol, see ActiveRecord::Type.register. You can
|
148
162
|
# also pass a type object directly, in place of a symbol.
|
149
163
|
#
|
@@ -190,8 +204,8 @@ module ActiveRecord
|
|
190
204
|
# The type of an attribute is given the opportunity to change how dirty
|
191
205
|
# tracking is performed. The methods +changed?+ and +changed_in_place?+
|
192
206
|
# will be called from ActiveModel::Dirty. See the documentation for those
|
193
|
-
# methods in
|
194
|
-
def attribute(name, cast_type, **options)
|
207
|
+
# methods in ActiveModel::Type::Value for more details.
|
208
|
+
def attribute(name, cast_type = Type::Value.new, **options)
|
195
209
|
name = name.to_s
|
196
210
|
reload_schema_from_cache
|
197
211
|
|
@@ -241,25 +255,24 @@ module ActiveRecord
|
|
241
255
|
end
|
242
256
|
|
243
257
|
private
|
258
|
+
NO_DEFAULT_PROVIDED = Object.new # :nodoc:
|
259
|
+
private_constant :NO_DEFAULT_PROVIDED
|
244
260
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
default_attribute = Attribute.from_database(name, value, type)
|
261
|
+
def define_default_attribute(name, value, type, from_user:)
|
262
|
+
if value == NO_DEFAULT_PROVIDED
|
263
|
+
default_attribute = _default_attributes[name].with_type(type)
|
264
|
+
elsif from_user
|
265
|
+
default_attribute = ActiveModel::Attribute::UserProvidedDefault.new(
|
266
|
+
name,
|
267
|
+
value,
|
268
|
+
type,
|
269
|
+
_default_attributes.fetch(name.to_s) { nil },
|
270
|
+
)
|
271
|
+
else
|
272
|
+
default_attribute = ActiveModel::Attribute.from_database(name, value, type)
|
273
|
+
end
|
274
|
+
_default_attributes[name] = default_attribute
|
260
275
|
end
|
261
|
-
_default_attributes[name] = default_attribute
|
262
|
-
end
|
263
276
|
end
|
264
277
|
end
|
265
278
|
end
|