activerecord 5.0.7.2 → 6.1.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 +4 -4
- data/CHANGELOG.md +829 -2015
- data/MIT-LICENSE +3 -1
- data/README.rdoc +11 -9
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record.rb +37 -29
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +30 -18
- data/lib/active_record/associations.rb +1714 -1596
- data/lib/active_record/associations/alias_tracker.rb +36 -42
- data/lib/active_record/associations/association.rb +143 -68
- data/lib/active_record/associations/association_scope.rb +98 -94
- data/lib/active_record/associations/belongs_to_association.rb +76 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
- data/lib/active_record/associations/builder/association.rb +27 -28
- data/lib/active_record/associations/builder/belongs_to.rb +52 -60
- data/lib/active_record/associations/builder/collection_association.rb +12 -22
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
- data/lib/active_record/associations/builder/has_many.rb +10 -2
- data/lib/active_record/associations/builder/has_one.rb +35 -2
- data/lib/active_record/associations/builder/singular_association.rb +5 -1
- data/lib/active_record/associations/collection_association.rb +104 -259
- data/lib/active_record/associations/collection_proxy.rb +169 -125
- data/lib/active_record/associations/foreign_association.rb +22 -0
- data/lib/active_record/associations/has_many_association.rb +46 -31
- data/lib/active_record/associations/has_many_through_association.rb +66 -46
- data/lib/active_record/associations/has_one_association.rb +71 -52
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +169 -180
- data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/preloader.rb +97 -104
- data/lib/active_record/associations/preloader/association.rb +109 -97
- 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 +27 -15
- data/lib/active_record/attribute_assignment.rb +55 -60
- data/lib/active_record/attribute_methods.rb +111 -141
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
- data/lib/active_record/attribute_methods/dirty.rb +172 -112
- data/lib/active_record/attribute_methods/primary_key.rb +88 -91
- data/lib/active_record/attribute_methods/query.rb +6 -8
- data/lib/active_record/attribute_methods/read.rb +18 -50
- data/lib/active_record/attribute_methods/serialization.rb +38 -10
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
- data/lib/active_record/attribute_methods/write.rb +25 -32
- data/lib/active_record/attributes.rb +69 -31
- data/lib/active_record/autosave_association.rb +102 -66
- data/lib/active_record/base.rb +16 -25
- data/lib/active_record/callbacks.rb +202 -43
- 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.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
- data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
- data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
- data/lib/active_record/connection_adapters/column.rb +55 -13
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -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 +79 -49
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -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 +6 -6
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
- 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/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 -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 +52 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -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 +98 -38
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -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 +426 -324
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
- data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -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 +5 -6
- 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 +282 -290
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +287 -45
- data/lib/active_record/core.rb +385 -181
- data/lib/active_record/counter_cache.rb +60 -28
- data/lib/active_record/database_configurations.rb +272 -0
- 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/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +87 -87
- data/lib/active_record/enum.rb +122 -47
- data/lib/active_record/errors.rb +153 -22
- data/lib/active_record/explain.rb +13 -8
- 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 +20 -22
- 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 +246 -507
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +168 -95
- data/lib/active_record/insert_all.rb +208 -0
- data/lib/active_record/integration.rb +114 -25
- data/lib/active_record/internal_metadata.rb +30 -24
- data/lib/active_record/legacy_yaml_adapter.rb +11 -5
- data/lib/active_record/locking/optimistic.rb +81 -85
- data/lib/active_record/locking/pessimistic.rb +22 -6
- data/lib/active_record/log_subscriber.rb +68 -31
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/migration.rb +439 -342
- data/lib/active_record/migration/command_recorder.rb +152 -98
- data/lib/active_record/migration/compatibility.rb +229 -60
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/model_schema.rb +230 -122
- data/lib/active_record/nested_attributes.rb +213 -203
- data/lib/active_record/no_touching.rb +11 -2
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +471 -97
- data/lib/active_record/query_cache.rb +23 -12
- data/lib/active_record/querying.rb +43 -25
- data/lib/active_record/railtie.rb +155 -43
- 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 +507 -195
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +245 -269
- data/lib/active_record/relation.rb +475 -324
- data/lib/active_record/relation/batches.rb +125 -72
- data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
- data/lib/active_record/relation/calculations.rb +267 -171
- data/lib/active_record/relation/delegation.rb +73 -69
- data/lib/active_record/relation/finder_methods.rb +238 -248
- data/lib/active_record/relation/from_clause.rb +7 -9
- data/lib/active_record/relation/merger.rb +95 -77
- data/lib/active_record/relation/predicate_builder.rb +109 -110
- data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +654 -374
- data/lib/active_record/relation/record_fetch_warning.rb +8 -6
- data/lib/active_record/relation/spawn_methods.rb +15 -14
- data/lib/active_record/relation/where_clause.rb +171 -109
- data/lib/active_record/result.rb +88 -51
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +73 -100
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +101 -69
- data/lib/active_record/schema_migration.rb +16 -12
- data/lib/active_record/scoping.rb +20 -20
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +39 -30
- data/lib/active_record/secure_token.rb +19 -9
- data/lib/active_record/serialization.rb +7 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +80 -29
- data/lib/active_record/store.rb +122 -42
- data/lib/active_record/suppressor.rb +6 -3
- data/lib/active_record/table_metadata.rb +51 -39
- data/lib/active_record/tasks/database_tasks.rb +332 -115
- data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
- data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +246 -0
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +26 -24
- data/lib/active_record/transactions.rb +121 -184
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +29 -17
- 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 +20 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +12 -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 -13
- data/lib/active_record/type_caster/map.rb +10 -6
- data/lib/active_record/validations.rb +8 -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/numericality.rb +35 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +52 -45
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +54 -0
- 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.rb +70 -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 +72 -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/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.rb +13 -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/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 +22 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
- data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
- 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 → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +141 -57
- 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_decorators.rb +0 -67
- 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/connection_specification.rb +0 -263
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
- 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/base_handler.rb +0 -17
- 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/relation/where_clause_factory.rb +0 -38
- 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,9 +16,8 @@ module ActiveRecord
|
|
14
16
|
when true then true
|
15
17
|
when false, nil then false
|
16
18
|
else
|
17
|
-
|
18
|
-
|
19
|
-
if Numeric === value || value !~ /[^0-9]/
|
19
|
+
if !type_for_attribute(attr_name) { false }
|
20
|
+
if Numeric === value || !value.match?(/[^0-9]/)
|
20
21
|
!value.to_i.zero?
|
21
22
|
else
|
22
23
|
return false if ActiveModel::Type::Boolean::FALSE_VALUES.include?(value)
|
@@ -30,11 +31,8 @@ module ActiveRecord
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
def attribute?(attribute_name)
|
36
|
-
query_attribute(attribute_name)
|
37
|
-
end
|
34
|
+
alias :attribute? :query_attribute
|
35
|
+
private :attribute?
|
38
36
|
end
|
39
37
|
end
|
40
38
|
end
|
@@ -1,47 +1,22 @@
|
|
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
|
-
# But sometimes the database might return columns with
|
17
|
-
# characters that are not allowed in normal method names (like
|
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, owner:)
|
11
|
+
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
12
|
+
owner, name
|
13
|
+
) do |temp_method_name, attr_name_expr|
|
14
|
+
owner <<
|
15
|
+
"def #{temp_method_name}" <<
|
16
|
+
" _read_attribute(#{attr_name_expr}) { |n| missing_attribute(n, caller) }" <<
|
17
|
+
"end"
|
37
18
|
end
|
38
|
-
STR
|
39
|
-
|
40
|
-
generated_attribute_methods.module_eval do
|
41
|
-
alias_method name, temp_method
|
42
|
-
undef_method temp_method
|
43
19
|
end
|
44
|
-
end
|
45
20
|
end
|
46
21
|
|
47
22
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after
|
@@ -49,27 +24,20 @@ module ActiveRecord
|
|
49
24
|
# to a date object, like Date.new(2004, 12, 12)).
|
50
25
|
def read_attribute(attr_name, &block)
|
51
26
|
name = attr_name.to_s
|
52
|
-
name = self.class.
|
53
|
-
|
27
|
+
name = self.class.attribute_aliases[name] || name
|
28
|
+
|
29
|
+
name = @primary_key if name == "id" && @primary_key
|
30
|
+
@attributes.fetch_value(name, &block)
|
54
31
|
end
|
55
32
|
|
56
33
|
# This method exists to avoid the expensive primary_key check internally, without
|
57
34
|
# breaking compatibility with the read_attribute API
|
58
|
-
|
59
|
-
|
60
|
-
# https://github.com/jruby/jruby/pull/2562
|
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
|
35
|
+
def _read_attribute(attr_name, &block) # :nodoc
|
36
|
+
@attributes.fetch_value(attr_name, &block)
|
68
37
|
end
|
69
38
|
|
70
39
|
alias :attribute :_read_attribute
|
71
40
|
private :attribute
|
72
|
-
|
73
41
|
end
|
74
42
|
end
|
75
43
|
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,9 +38,15 @@ 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
|
#
|
44
|
+
# ==== Options
|
45
|
+
#
|
46
|
+
# +default+ The default value to use when no value is provided. If this option
|
47
|
+
# is not passed, the previous default value (if any) will be used.
|
48
|
+
# Otherwise, the default will be +nil+.
|
49
|
+
#
|
32
50
|
# ==== Example
|
33
51
|
#
|
34
52
|
# # Serialize a preferences attribute.
|
@@ -45,22 +63,32 @@ module ActiveRecord
|
|
45
63
|
# class User < ActiveRecord::Base
|
46
64
|
# serialize :preferences, Hash
|
47
65
|
# end
|
48
|
-
def serialize(attr_name, class_name_or_coder = Object)
|
66
|
+
def serialize(attr_name, class_name_or_coder = Object, **options)
|
49
67
|
# When ::JSON is used, force it to go through the Active Support JSON encoder
|
50
68
|
# to ensure special objects (e.g. Active Record models) are dumped correctly
|
51
69
|
# using the #as_json hook.
|
52
70
|
coder = if class_name_or_coder == ::JSON
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
71
|
+
Coders::JSON
|
72
|
+
elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
|
73
|
+
class_name_or_coder
|
74
|
+
else
|
75
|
+
Coders::YAMLColumn.new(attr_name, class_name_or_coder)
|
76
|
+
end
|
77
|
+
|
78
|
+
decorate_attribute_type(attr_name.to_s, **options) do |cast_type|
|
79
|
+
if type_incompatible_with_serialize?(cast_type, class_name_or_coder)
|
80
|
+
raise ColumnNotSerializableError.new(attr_name, cast_type)
|
81
|
+
end
|
59
82
|
|
60
|
-
|
61
|
-
Type::Serialized.new(type, coder)
|
83
|
+
Type::Serialized.new(cast_type, coder)
|
62
84
|
end
|
63
85
|
end
|
86
|
+
|
87
|
+
private
|
88
|
+
def type_incompatible_with_serialize?(type, class_name)
|
89
|
+
type.is_a?(ActiveRecord::Type::Json) && class_name == ::JSON ||
|
90
|
+
type.respond_to?(:type_cast_array, true) && class_name == ::Array
|
91
|
+
end
|
64
92
|
end
|
65
93
|
end
|
66
94
|
end
|
@@ -1,9 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/try"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
module AttributeMethods
|
5
7
|
module TimeZoneConversion
|
6
8
|
class TimeZoneConverter < DelegateClass(Type::Value) # :nodoc:
|
9
|
+
def self.new(subtype)
|
10
|
+
self === subtype ? subtype : super
|
11
|
+
end
|
12
|
+
|
7
13
|
def deserialize(value)
|
8
14
|
convert_time_to_time_zone(super)
|
9
15
|
end
|
@@ -25,91 +31,57 @@ module ActiveRecord
|
|
25
31
|
end
|
26
32
|
|
27
33
|
private
|
34
|
+
def convert_time_to_time_zone(value)
|
35
|
+
return if value.nil?
|
28
36
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
else
|
37
|
-
map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
|
37
|
+
if value.acts_like?(:time)
|
38
|
+
value.in_time_zone
|
39
|
+
elsif value.is_a?(::Float)
|
40
|
+
value
|
41
|
+
else
|
42
|
+
map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
|
43
|
+
end
|
38
44
|
end
|
39
|
-
end
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
def set_time_zone_without_conversion(value)
|
47
|
+
::Time.zone.local_to_utc(value).try(:in_time_zone) if value
|
48
|
+
end
|
44
49
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
def map_avoiding_infinite_recursion(value)
|
51
|
+
map(value) do |v|
|
52
|
+
if value.equal?(v)
|
53
|
+
nil
|
54
|
+
else
|
55
|
+
yield(v)
|
56
|
+
end
|
51
57
|
end
|
52
58
|
end
|
53
|
-
end
|
54
59
|
end
|
55
60
|
|
56
61
|
extend ActiveSupport::Concern
|
57
62
|
|
58
63
|
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 = []
|
64
|
+
mattr_accessor :time_zone_aware_attributes, instance_writer: false, default: false
|
64
65
|
|
65
|
-
class_attribute :
|
66
|
-
|
66
|
+
class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false, default: []
|
67
|
+
class_attribute :time_zone_aware_types, instance_writer: false, default: [ :datetime, :time ]
|
67
68
|
end
|
68
69
|
|
69
|
-
module ClassMethods
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
# We need to apply this decorator here, rather than on module inclusion. The closure
|
74
|
-
# created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
|
75
|
-
# sub class being decorated. As such, changes to `time_zone_aware_attributes`, or
|
76
|
-
# `skip_time_zone_conversion_for_attributes` would not be picked up.
|
77
|
-
subclass.class_eval do
|
78
|
-
matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) }
|
79
|
-
decorate_matching_attribute_types(matcher, :_time_zone_conversion) do |type|
|
80
|
-
TimeZoneConverter.new(type)
|
81
|
-
end
|
70
|
+
module ClassMethods # :nodoc:
|
71
|
+
def define_attribute(name, cast_type, **)
|
72
|
+
if create_time_zone_conversion_attribute?(name, cast_type)
|
73
|
+
cast_type = TimeZoneConverter.new(cast_type)
|
82
74
|
end
|
83
75
|
super
|
84
76
|
end
|
85
77
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
time_zone_aware_types.include?(cast_type.type)
|
91
|
-
|
92
|
-
if enabled_for_column &&
|
93
|
-
!result &&
|
94
|
-
cast_type.type == :time &&
|
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`.
|
100
|
-
|
101
|
-
To keep the old behavior, you must add the following to your initializer:
|
102
|
-
|
103
|
-
config.active_record.time_zone_aware_types = [:datetime]
|
104
|
-
|
105
|
-
To use the new behavior, add the following:
|
78
|
+
private
|
79
|
+
def create_time_zone_conversion_attribute?(name, cast_type)
|
80
|
+
enabled_for_column = time_zone_aware_attributes &&
|
81
|
+
!skip_time_zone_conversion_for_attributes.include?(name.to_sym)
|
106
82
|
|
107
|
-
|
108
|
-
MESSAGE
|
83
|
+
enabled_for_column && time_zone_aware_types.include?(cast_type.type)
|
109
84
|
end
|
110
|
-
|
111
|
-
result
|
112
|
-
end
|
113
85
|
end
|
114
86
|
end
|
115
87
|
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,44 @@ 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
|
-
write_attribute(name, value)
|
12
|
+
module ClassMethods # :nodoc:
|
13
|
+
private
|
14
|
+
def define_method_attribute=(name, owner:)
|
15
|
+
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
16
|
+
owner, name, writer: true,
|
17
|
+
) do |temp_method_name, attr_name_expr|
|
18
|
+
owner <<
|
19
|
+
"def #{temp_method_name}(value)" <<
|
20
|
+
" _write_attribute(#{attr_name_expr}, value)" <<
|
21
|
+
"end"
|
21
22
|
end
|
22
|
-
|
23
|
-
undef_method :__temp__#{safe_name}=
|
24
|
-
STR
|
25
|
-
end
|
23
|
+
end
|
26
24
|
end
|
27
25
|
|
28
26
|
# Updates the attribute identified by <tt>attr_name</tt> with the
|
29
27
|
# specified +value+. Empty strings for Integer and Float columns are
|
30
28
|
# turned into +nil+.
|
31
29
|
def write_attribute(attr_name, value)
|
32
|
-
|
33
|
-
|
30
|
+
name = attr_name.to_s
|
31
|
+
name = self.class.attribute_aliases[name] || name
|
34
32
|
|
35
|
-
|
36
|
-
|
33
|
+
name = @primary_key if name == "id" && @primary_key
|
34
|
+
@attributes.write_from_user(name, value)
|
37
35
|
end
|
38
36
|
|
39
|
-
|
40
|
-
#
|
41
|
-
def
|
42
|
-
|
37
|
+
# This method exists to avoid the expensive primary_key check internally, without
|
38
|
+
# breaking compatibility with the write_attribute API
|
39
|
+
def _write_attribute(attr_name, value) # :nodoc:
|
40
|
+
@attributes.write_from_user(attr_name, value)
|
43
41
|
end
|
44
42
|
|
45
|
-
|
46
|
-
|
47
|
-
attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
|
43
|
+
alias :attribute= :_write_attribute
|
44
|
+
private :attribute=
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
else
|
46
|
+
private
|
47
|
+
def write_attribute_without_type_cast(attr_name, value)
|
52
48
|
@attributes.write_cast_value(attr_name, value)
|
53
49
|
end
|
54
|
-
|
55
|
-
value
|
56
|
-
end
|
57
50
|
end
|
58
51
|
end
|
59
52
|
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,11 +8,13 @@ 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
|
15
|
+
##
|
16
|
+
# :call-seq: attribute(name, cast_type = nil, **options)
|
17
|
+
#
|
14
18
|
# Defines an attribute with a type on this model. It will override the
|
15
19
|
# type of existing attributes if needed. This allows control over how
|
16
20
|
# values are converted to and from SQL when assigned to a model. It also
|
@@ -40,6 +44,9 @@ module ActiveRecord
|
|
40
44
|
# +range+ (PostgreSQL only) specifies that the type should be a range (see the
|
41
45
|
# examples below).
|
42
46
|
#
|
47
|
+
# When using a symbol for +cast_type+, extra options are forwarded to the
|
48
|
+
# constructor of the type object.
|
49
|
+
#
|
43
50
|
# ==== Examples
|
44
51
|
#
|
45
52
|
# The type detected by Active Record can be overridden.
|
@@ -56,7 +63,7 @@ module ActiveRecord
|
|
56
63
|
# store_listing = StoreListing.new(price_in_cents: '10.1')
|
57
64
|
#
|
58
65
|
# # before
|
59
|
-
# store_listing.price_in_cents # => BigDecimal
|
66
|
+
# store_listing.price_in_cents # => BigDecimal(10.1)
|
60
67
|
#
|
61
68
|
# class StoreListing < ActiveRecord::Base
|
62
69
|
# attribute :price_in_cents, :integer
|
@@ -111,12 +118,22 @@ module ActiveRecord
|
|
111
118
|
# my_float_range: 1.0..3.5
|
112
119
|
# }
|
113
120
|
#
|
121
|
+
# Passing options to the type constructor
|
122
|
+
#
|
123
|
+
# # app/models/my_model.rb
|
124
|
+
# class MyModel < ActiveRecord::Base
|
125
|
+
# attribute :small_int, :integer, limit: 2
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
# MyModel.create(small_int: 65537)
|
129
|
+
# # => Error: 65537 is out of range for the limit of two bytes
|
130
|
+
#
|
114
131
|
# ==== Creating Custom Types
|
115
132
|
#
|
116
133
|
# Users may also define their own custom types, as long as they respond
|
117
134
|
# to the methods defined on the value type. The method +deserialize+ or
|
118
135
|
# +cast+ will be called on your type object, with raw input from the
|
119
|
-
# database or from your controllers. See
|
136
|
+
# database or from your controllers. See ActiveModel::Type::Value for the
|
120
137
|
# expected API. It is recommended that your type objects inherit from an
|
121
138
|
# existing type, or from ActiveRecord::Type::Value
|
122
139
|
#
|
@@ -143,7 +160,7 @@ module ActiveRecord
|
|
143
160
|
# store_listing.price_in_cents # => 1000
|
144
161
|
#
|
145
162
|
# For more details on creating custom types, see the documentation for
|
146
|
-
#
|
163
|
+
# ActiveModel::Type::Value. For more details on registering your types
|
147
164
|
# to be referenced by a symbol, see ActiveRecord::Type.register. You can
|
148
165
|
# also pass a type object directly, in place of a symbol.
|
149
166
|
#
|
@@ -156,7 +173,7 @@ module ActiveRecord
|
|
156
173
|
# class Money < Struct.new(:amount, :currency)
|
157
174
|
# end
|
158
175
|
#
|
159
|
-
# class MoneyType < Type::Value
|
176
|
+
# class MoneyType < ActiveRecord::Type::Value
|
160
177
|
# def initialize(currency_converter:)
|
161
178
|
# @currency_converter = currency_converter
|
162
179
|
# end
|
@@ -190,14 +207,14 @@ module ActiveRecord
|
|
190
207
|
# The type of an attribute is given the opportunity to change how dirty
|
191
208
|
# tracking is performed. The methods +changed?+ and +changed_in_place?+
|
192
209
|
# will be called from ActiveModel::Dirty. See the documentation for those
|
193
|
-
# methods in
|
194
|
-
def attribute(name, cast_type, **options)
|
210
|
+
# methods in ActiveModel::Type::Value for more details.
|
211
|
+
def attribute(name, cast_type = nil, **options, &block)
|
195
212
|
name = name.to_s
|
196
213
|
reload_schema_from_cache
|
197
214
|
|
198
215
|
self.attributes_to_define_after_schema_loads =
|
199
216
|
attributes_to_define_after_schema_loads.merge(
|
200
|
-
name => [cast_type, options]
|
217
|
+
name => [cast_type || block, options]
|
201
218
|
)
|
202
219
|
end
|
203
220
|
|
@@ -232,34 +249,55 @@ module ActiveRecord
|
|
232
249
|
def load_schema! # :nodoc:
|
233
250
|
super
|
234
251
|
attributes_to_define_after_schema_loads.each do |name, (type, options)|
|
235
|
-
|
236
|
-
type = ActiveRecord::Type.lookup(type, **options.except(:default))
|
237
|
-
end
|
238
|
-
|
239
|
-
define_attribute(name, type, **options.slice(:default))
|
252
|
+
define_attribute(name, _lookup_cast_type(name, type, options), **options.slice(:default))
|
240
253
|
end
|
241
254
|
end
|
242
255
|
|
243
256
|
private
|
257
|
+
NO_DEFAULT_PROVIDED = Object.new # :nodoc:
|
258
|
+
private_constant :NO_DEFAULT_PROVIDED
|
244
259
|
|
245
|
-
|
246
|
-
|
260
|
+
def define_default_attribute(name, value, type, from_user:)
|
261
|
+
if value == NO_DEFAULT_PROVIDED
|
262
|
+
default_attribute = _default_attributes[name].with_type(type)
|
263
|
+
elsif from_user
|
264
|
+
default_attribute = ActiveModel::Attribute::UserProvidedDefault.new(
|
265
|
+
name,
|
266
|
+
value,
|
267
|
+
type,
|
268
|
+
_default_attributes.fetch(name.to_s) { nil },
|
269
|
+
)
|
270
|
+
else
|
271
|
+
default_attribute = ActiveModel::Attribute.from_database(name, value, type)
|
272
|
+
end
|
273
|
+
_default_attributes[name] = default_attribute
|
274
|
+
end
|
247
275
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
276
|
+
def decorate_attribute_type(attr_name, **default)
|
277
|
+
type, options = attributes_to_define_after_schema_loads[attr_name]
|
278
|
+
|
279
|
+
default.with_defaults!(default: options[:default]) if options&.key?(:default)
|
280
|
+
|
281
|
+
attribute(attr_name, **default) do |cast_type|
|
282
|
+
if type && !type.is_a?(Proc)
|
283
|
+
cast_type = _lookup_cast_type(attr_name, type, options)
|
284
|
+
end
|
285
|
+
|
286
|
+
yield cast_type
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def _lookup_cast_type(name, type, options)
|
291
|
+
case type
|
292
|
+
when Symbol
|
293
|
+
adapter_name = ActiveRecord::Type.adapter_name_from(self)
|
294
|
+
ActiveRecord::Type.lookup(type, **options.except(:default), adapter: adapter_name)
|
295
|
+
when Proc
|
296
|
+
type[type_for_attribute(name)]
|
297
|
+
else
|
298
|
+
type || type_for_attribute(name)
|
299
|
+
end
|
260
300
|
end
|
261
|
-
_default_attributes[name] = default_attribute
|
262
|
-
end
|
263
301
|
end
|
264
302
|
end
|
265
303
|
end
|