activerecord 5.2.3 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +898 -532
- data/MIT-LICENSE +3 -1
- data/README.rdoc +7 -5
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +5 -4
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +95 -42
- data/lib/active_record/associations/association_scope.rb +21 -21
- data/lib/active_record/associations/belongs_to_association.rb +50 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -5
- data/lib/active_record/associations/builder/association.rb +23 -21
- data/lib/active_record/associations/builder/belongs_to.rb +29 -59
- data/lib/active_record/associations/builder/collection_association.rb +10 -19
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
- data/lib/active_record/associations/builder/has_many.rb +8 -2
- data/lib/active_record/associations/builder/has_one.rb +33 -2
- data/lib/active_record/associations/builder/singular_association.rb +3 -1
- data/lib/active_record/associations/collection_association.rb +31 -29
- data/lib/active_record/associations/collection_proxy.rb +25 -21
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +26 -13
- data/lib/active_record/associations/has_many_through_association.rb +27 -28
- data/lib/active_record/associations/has_one_association.rb +43 -31
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +54 -12
- data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +91 -60
- data/lib/active_record/associations/preloader/association.rb +71 -43
- data/lib/active_record/associations/preloader/through_association.rb +49 -40
- data/lib/active_record/associations/preloader.rb +48 -35
- data/lib/active_record/associations/singular_association.rb +3 -17
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +133 -25
- data/lib/active_record/attribute_assignment.rb +17 -19
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
- data/lib/active_record/attribute_methods/dirty.rb +101 -40
- data/lib/active_record/attribute_methods/primary_key.rb +20 -25
- data/lib/active_record/attribute_methods/query.rb +4 -8
- data/lib/active_record/attribute_methods/read.rb +14 -56
- data/lib/active_record/attribute_methods/serialization.rb +12 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +18 -34
- data/lib/active_record/attribute_methods.rb +81 -143
- data/lib/active_record/attributes.rb +45 -8
- data/lib/active_record/autosave_association.rb +76 -47
- data/lib/active_record/base.rb +4 -17
- data/lib/active_record/callbacks.rb +158 -43
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +293 -132
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +21 -17
- data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +203 -90
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +381 -146
- data/lib/active_record/connection_adapters/abstract/transaction.rb +155 -68
- data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -98
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
- data/lib/active_record/connection_adapters/column.rb +30 -12
- 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 +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +86 -32
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
- 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 +37 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +38 -54
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +222 -112
- data/lib/active_record/connection_adapters/schema_cache.rb +127 -21
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +19 -6
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +175 -187
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_handling.rb +285 -33
- data/lib/active_record/core.rb +308 -100
- data/lib/active_record/counter_cache.rb +8 -30
- 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 +3 -4
- data/lib/active_record/enum.rb +71 -17
- data/lib/active_record/errors.rb +62 -19
- data/lib/active_record/explain.rb +10 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- 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 +197 -481
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +53 -24
- data/lib/active_record/insert_all.rb +208 -0
- data/lib/active_record/integration.rb +67 -17
- data/lib/active_record/internal_metadata.rb +26 -9
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +26 -22
- data/lib/active_record/locking/pessimistic.rb +9 -5
- data/lib/active_record/log_subscriber.rb +34 -35
- 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 +96 -44
- data/lib/active_record/migration/compatibility.rb +141 -64
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +205 -156
- data/lib/active_record/model_schema.rb +148 -22
- data/lib/active_record/nested_attributes.rb +4 -7
- data/lib/active_record/no_touching.rb +8 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +267 -59
- data/lib/active_record/query_cache.rb +21 -4
- data/lib/active_record/querying.rb +40 -23
- data/lib/active_record/railtie.rb +115 -58
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +402 -78
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +113 -101
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/batches.rb +44 -35
- data/lib/active_record/relation/calculations.rb +157 -93
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +65 -40
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +32 -40
- data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -7
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +58 -40
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +487 -199
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +9 -9
- data/lib/active_record/relation/where_clause.rb +108 -58
- data/lib/active_record/relation.rb +375 -104
- data/lib/active_record/result.rb +64 -38
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +22 -41
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +54 -9
- data/lib/active_record/schema_migration.rb +7 -9
- data/lib/active_record/scoping/default.rb +6 -8
- data/lib/active_record/scoping/named.rb +17 -24
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +51 -8
- data/lib/active_record/store.rb +88 -9
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -43
- data/lib/active_record/tasks/database_tasks.rb +276 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
- data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
- data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +246 -0
- data/lib/active_record/timestamp.rb +43 -32
- data/lib/active_record/touch_later.rb +23 -22
- data/lib/active_record/transactions.rb +59 -117
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +10 -5
- data/lib/active_record/type_caster/connection.rb +15 -15
- data/lib/active_record/type_caster/map.rb +8 -8
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +38 -30
- data/lib/active_record/validations.rb +4 -3
- data/lib/active_record.rb +13 -12
- 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 +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/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 +0 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
- data/lib/rails/generators/active_record/migration.rb +19 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
- 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 +10 -1
- metadata +117 -32
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
- data/lib/active_record/relation/where_clause_factory.rb +0 -34
| @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            require "mutex_m"
         | 
| 4 | 
            +
            require "active_support/core_ext/enumerable"
         | 
| 4 5 |  | 
| 5 6 | 
             
            module ActiveRecord
         | 
| 6 7 | 
             
              # = Active Record Attribute Methods
         | 
| @@ -18,25 +19,25 @@ module ActiveRecord | |
| 18 19 | 
             
                  include TimeZoneConversion
         | 
| 19 20 | 
             
                  include Dirty
         | 
| 20 21 | 
             
                  include Serialization
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                  delegate :column_for_attribute, to: :class
         | 
| 23 22 | 
             
                end
         | 
| 24 23 |  | 
| 25 | 
            -
                 | 
| 26 | 
            -
                  def self.set_name_cache(name, value)
         | 
| 27 | 
            -
                    const_name = "ATTR_#{name}"
         | 
| 28 | 
            -
                    unless const_defined? const_name
         | 
| 29 | 
            -
                      const_set const_name, value.dup.freeze
         | 
| 30 | 
            -
                    end
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
                }
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                BLACKLISTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
         | 
| 24 | 
            +
                RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
         | 
| 35 25 |  | 
| 36 26 | 
             
                class GeneratedAttributeMethods < Module #:nodoc:
         | 
| 37 27 | 
             
                  include Mutex_m
         | 
| 38 28 | 
             
                end
         | 
| 39 29 |  | 
| 30 | 
            +
                class << self
         | 
| 31 | 
            +
                  def dangerous_attribute_methods # :nodoc:
         | 
| 32 | 
            +
                    @dangerous_attribute_methods ||= (
         | 
| 33 | 
            +
                      Base.instance_methods +
         | 
| 34 | 
            +
                      Base.private_instance_methods -
         | 
| 35 | 
            +
                      Base.superclass.instance_methods -
         | 
| 36 | 
            +
                      Base.superclass.private_instance_methods
         | 
| 37 | 
            +
                    ).map { |m| -m.to_s }.to_set.freeze
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 40 41 | 
             
                module ClassMethods
         | 
| 41 42 | 
             
                  def inherited(child_class) #:nodoc:
         | 
| 42 43 | 
             
                    child_class.initialize_generated_modules
         | 
| @@ -44,7 +45,8 @@ module ActiveRecord | |
| 44 45 | 
             
                  end
         | 
| 45 46 |  | 
| 46 47 | 
             
                  def initialize_generated_modules # :nodoc:
         | 
| 47 | 
            -
                    @generated_attribute_methods = GeneratedAttributeMethods.new
         | 
| 48 | 
            +
                    @generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
         | 
| 49 | 
            +
                    private_constant :GeneratedAttributeMethods
         | 
| 48 50 | 
             
                    @attribute_methods_generated = false
         | 
| 49 51 | 
             
                    include @generated_attribute_methods
         | 
| 50 52 |  | 
| @@ -59,7 +61,7 @@ module ActiveRecord | |
| 59 61 | 
             
                    # attribute methods.
         | 
| 60 62 | 
             
                    generated_attribute_methods.synchronize do
         | 
| 61 63 | 
             
                      return false if @attribute_methods_generated
         | 
| 62 | 
            -
                      superclass.define_attribute_methods unless  | 
| 64 | 
            +
                      superclass.define_attribute_methods unless base_class?
         | 
| 63 65 | 
             
                      super(attribute_names)
         | 
| 64 66 | 
             
                      @attribute_methods_generated = true
         | 
| 65 67 | 
             
                    end
         | 
| @@ -105,7 +107,7 @@ module ActiveRecord | |
| 105 107 | 
             
                  # A method name is 'dangerous' if it is already (re)defined by Active Record, but
         | 
| 106 108 | 
             
                  # not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
         | 
| 107 109 | 
             
                  def dangerous_attribute_method?(name) # :nodoc:
         | 
| 108 | 
            -
                     | 
| 110 | 
            +
                    ::ActiveRecord::AttributeMethods.dangerous_attribute_methods.include?(name.to_s)
         | 
| 109 111 | 
             
                  end
         | 
| 110 112 |  | 
| 111 113 | 
             
                  def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
         | 
| @@ -123,13 +125,11 @@ module ActiveRecord | |
| 123 125 | 
             
                  # A class method is 'dangerous' if it is already (re)defined by Active Record, but
         | 
| 124 126 | 
             
                  # not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
         | 
| 125 127 | 
             
                  def dangerous_class_method?(method_name)
         | 
| 126 | 
            -
                     | 
| 127 | 
            -
                  end
         | 
| 128 | 
            +
                    return true if RESTRICTED_CLASS_METHODS.include?(method_name.to_s)
         | 
| 128 129 |  | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
                        klass.method(name).owner != superklass.method(name).owner
         | 
| 130 | 
            +
                    if Base.respond_to?(method_name, true)
         | 
| 131 | 
            +
                      if Object.respond_to?(method_name, true)
         | 
| 132 | 
            +
                        Base.method(method_name).owner != Object.method(method_name).owner
         | 
| 133 133 | 
             
                      else
         | 
| 134 134 | 
             
                        true
         | 
| 135 135 | 
             
                      end
         | 
| @@ -148,7 +148,7 @@ module ActiveRecord | |
| 148 148 | 
             
                  #   Person.attribute_method?(:age=)    # => true
         | 
| 149 149 | 
             
                  #   Person.attribute_method?(:nothing) # => false
         | 
| 150 150 | 
             
                  def attribute_method?(attribute)
         | 
| 151 | 
            -
                    super || (table_exists? && column_names.include?(attribute.to_s. | 
| 151 | 
            +
                    super || (table_exists? && column_names.include?(attribute.to_s.delete_suffix("=")))
         | 
| 152 152 | 
             
                  end
         | 
| 153 153 |  | 
| 154 154 | 
             
                  # Returns an array of column names as strings if it's not an abstract class and
         | 
| @@ -164,90 +164,27 @@ module ActiveRecord | |
| 164 164 | 
             
                      attribute_types.keys
         | 
| 165 165 | 
             
                    else
         | 
| 166 166 | 
             
                      []
         | 
| 167 | 
            -
                    end
         | 
| 168 | 
            -
                  end
         | 
| 169 | 
            -
             | 
| 170 | 
            -
                  # Regexp whitelist. Matches the following:
         | 
| 171 | 
            -
                  #   "#{table_name}.#{column_name}"
         | 
| 172 | 
            -
                  #   "#{column_name}"
         | 
| 173 | 
            -
                  COLUMN_NAME_WHITELIST = /\A(?:\w+\.)?\w+\z/i
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                  # Regexp whitelist. Matches the following:
         | 
| 176 | 
            -
                  #   "#{table_name}.#{column_name}"
         | 
| 177 | 
            -
                  #   "#{table_name}.#{column_name} #{direction}"
         | 
| 178 | 
            -
                  #   "#{table_name}.#{column_name} #{direction} NULLS FIRST"
         | 
| 179 | 
            -
                  #   "#{table_name}.#{column_name} NULLS LAST"
         | 
| 180 | 
            -
                  #   "#{column_name}"
         | 
| 181 | 
            -
                  #   "#{column_name} #{direction}"
         | 
| 182 | 
            -
                  #   "#{column_name} #{direction} NULLS FIRST"
         | 
| 183 | 
            -
                  #   "#{column_name} NULLS LAST"
         | 
| 184 | 
            -
                  COLUMN_NAME_ORDER_WHITELIST = /
         | 
| 185 | 
            -
                    \A
         | 
| 186 | 
            -
                    (?:\w+\.)?
         | 
| 187 | 
            -
                    \w+
         | 
| 188 | 
            -
                    (?:\s+asc|\s+desc)?
         | 
| 189 | 
            -
                    (?:\s+nulls\s+(?:first|last))?
         | 
| 190 | 
            -
                    \z
         | 
| 191 | 
            -
                  /ix
         | 
| 192 | 
            -
             | 
| 193 | 
            -
                  def enforce_raw_sql_whitelist(args, whitelist: COLUMN_NAME_WHITELIST) # :nodoc:
         | 
| 194 | 
            -
                    unexpected = args.reject do |arg|
         | 
| 195 | 
            -
                      arg.kind_of?(Arel::Node) ||
         | 
| 196 | 
            -
                        arg.is_a?(Arel::Nodes::SqlLiteral) ||
         | 
| 197 | 
            -
                        arg.is_a?(Arel::Attributes::Attribute) ||
         | 
| 198 | 
            -
                        arg.to_s.split(/\s*,\s*/).all? { |part| whitelist.match?(part) }
         | 
| 199 | 
            -
                    end
         | 
| 200 | 
            -
             | 
| 201 | 
            -
                    return if unexpected.none?
         | 
| 202 | 
            -
             | 
| 203 | 
            -
                    if allow_unsafe_raw_sql == :deprecated
         | 
| 204 | 
            -
                      ActiveSupport::Deprecation.warn(
         | 
| 205 | 
            -
                        "Dangerous query method (method whose arguments are used as raw " \
         | 
| 206 | 
            -
                        "SQL) called with non-attribute argument(s): " \
         | 
| 207 | 
            -
                        "#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
         | 
| 208 | 
            -
                        "arguments will be disallowed in Rails 6.0. This method should " \
         | 
| 209 | 
            -
                        "not be called with user-provided values, such as request " \
         | 
| 210 | 
            -
                        "parameters or model attributes. Known-safe values can be passed " \
         | 
| 211 | 
            -
                        "by wrapping them in Arel.sql()."
         | 
| 212 | 
            -
                      )
         | 
| 213 | 
            -
                    else
         | 
| 214 | 
            -
                      raise(ActiveRecord::UnknownAttributeReference,
         | 
| 215 | 
            -
                        "Query method called with non-attribute argument(s): " +
         | 
| 216 | 
            -
                        unexpected.map(&:inspect).join(", ")
         | 
| 217 | 
            -
                      )
         | 
| 218 | 
            -
                    end
         | 
| 167 | 
            +
                    end.freeze
         | 
| 219 168 | 
             
                  end
         | 
| 220 169 |  | 
| 221 170 | 
             
                  # Returns true if the given attribute exists, otherwise false.
         | 
| 222 171 | 
             
                  #
         | 
| 223 172 | 
             
                  #   class Person < ActiveRecord::Base
         | 
| 173 | 
            +
                  #     alias_attribute :new_name, :name
         | 
| 224 174 | 
             
                  #   end
         | 
| 225 175 | 
             
                  #
         | 
| 226 | 
            -
                  #   Person.has_attribute?('name') | 
| 227 | 
            -
                  #   Person.has_attribute?( | 
| 228 | 
            -
                  #   Person.has_attribute?(: | 
| 176 | 
            +
                  #   Person.has_attribute?('name')     # => true
         | 
| 177 | 
            +
                  #   Person.has_attribute?('new_name') # => true
         | 
| 178 | 
            +
                  #   Person.has_attribute?(:age)       # => true
         | 
| 179 | 
            +
                  #   Person.has_attribute?(:nothing)   # => false
         | 
| 229 180 | 
             
                  def has_attribute?(attr_name)
         | 
| 230 | 
            -
                     | 
| 181 | 
            +
                    attr_name = attr_name.to_s
         | 
| 182 | 
            +
                    attr_name = attribute_aliases[attr_name] || attr_name
         | 
| 183 | 
            +
                    attribute_types.key?(attr_name)
         | 
| 231 184 | 
             
                  end
         | 
| 232 185 |  | 
| 233 | 
            -
                   | 
| 234 | 
            -
             | 
| 235 | 
            -
                  # named attribute does not exist.
         | 
| 236 | 
            -
                  #
         | 
| 237 | 
            -
                  #   class Person < ActiveRecord::Base
         | 
| 238 | 
            -
                  #   end
         | 
| 239 | 
            -
                  #
         | 
| 240 | 
            -
                  #   person = Person.new
         | 
| 241 | 
            -
                  #   person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
         | 
| 242 | 
            -
                  #   # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
         | 
| 243 | 
            -
                  #
         | 
| 244 | 
            -
                  #   person.column_for_attribute(:nothing)
         | 
| 245 | 
            -
                  #   # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
         | 
| 246 | 
            -
                  def column_for_attribute(name)
         | 
| 247 | 
            -
                    name = name.to_s
         | 
| 248 | 
            -
                    columns_hash.fetch(name) do
         | 
| 249 | 
            -
                      ConnectionAdapters::NullColumn.new(name)
         | 
| 250 | 
            -
                    end
         | 
| 186 | 
            +
                  def _has_attribute?(attr_name) # :nodoc:
         | 
| 187 | 
            +
                    attribute_types.key?(attr_name)
         | 
| 251 188 | 
             
                  end
         | 
| 252 189 | 
             
                end
         | 
| 253 190 |  | 
| @@ -270,21 +207,14 @@ module ActiveRecord | |
| 270 207 | 
             
                def respond_to?(name, include_private = false)
         | 
| 271 208 | 
             
                  return false unless super
         | 
| 272 209 |  | 
| 273 | 
            -
                  case name
         | 
| 274 | 
            -
                  when :to_partial_path
         | 
| 275 | 
            -
                    name = "to_partial_path".freeze
         | 
| 276 | 
            -
                  when :to_model
         | 
| 277 | 
            -
                    name = "to_model".freeze
         | 
| 278 | 
            -
                  else
         | 
| 279 | 
            -
                    name = name.to_s
         | 
| 280 | 
            -
                  end
         | 
| 281 | 
            -
             | 
| 282 210 | 
             
                  # If the result is true then check for the select case.
         | 
| 283 211 | 
             
                  # For queries selecting a subset of columns, return false for unselected columns.
         | 
| 284 212 | 
             
                  # We check defined?(@attributes) not to issue warnings if called on objects that
         | 
| 285 213 | 
             
                  # have been allocated but not yet initialized.
         | 
| 286 | 
            -
                  if defined?(@attributes) | 
| 287 | 
            -
                     | 
| 214 | 
            +
                  if defined?(@attributes)
         | 
| 215 | 
            +
                    if name = self.class.symbol_column_to_string(name.to_sym)
         | 
| 216 | 
            +
                      return _has_attribute?(name)
         | 
| 217 | 
            +
                    end
         | 
| 288 218 | 
             
                  end
         | 
| 289 219 |  | 
| 290 220 | 
             
                  true
         | 
| @@ -293,14 +223,22 @@ module ActiveRecord | |
| 293 223 | 
             
                # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
         | 
| 294 224 | 
             
                #
         | 
| 295 225 | 
             
                #   class Person < ActiveRecord::Base
         | 
| 226 | 
            +
                #     alias_attribute :new_name, :name
         | 
| 296 227 | 
             
                #   end
         | 
| 297 228 | 
             
                #
         | 
| 298 229 | 
             
                #   person = Person.new
         | 
| 299 | 
            -
                #   person.has_attribute?(:name) | 
| 300 | 
            -
                #   person.has_attribute?( | 
| 301 | 
            -
                #   person.has_attribute?( | 
| 230 | 
            +
                #   person.has_attribute?(:name)     # => true
         | 
| 231 | 
            +
                #   person.has_attribute?(:new_name) # => true
         | 
| 232 | 
            +
                #   person.has_attribute?('age')     # => true
         | 
| 233 | 
            +
                #   person.has_attribute?(:nothing)  # => false
         | 
| 302 234 | 
             
                def has_attribute?(attr_name)
         | 
| 303 | 
            -
                   | 
| 235 | 
            +
                  attr_name = attr_name.to_s
         | 
| 236 | 
            +
                  attr_name = self.class.attribute_aliases[attr_name] || attr_name
         | 
| 237 | 
            +
                  @attributes.key?(attr_name)
         | 
| 238 | 
            +
                end
         | 
| 239 | 
            +
             | 
| 240 | 
            +
                def _has_attribute?(attr_name) # :nodoc:
         | 
| 241 | 
            +
                  @attributes.key?(attr_name)
         | 
| 304 242 | 
             
                end
         | 
| 305 243 |  | 
| 306 244 | 
             
                # Returns an array of names for the attributes available on this object.
         | 
| @@ -344,15 +282,10 @@ module ActiveRecord | |
| 344 282 | 
             
                #   person.attribute_for_inspect(:tag_ids)
         | 
| 345 283 | 
             
                #   # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
         | 
| 346 284 | 
             
                def attribute_for_inspect(attr_name)
         | 
| 347 | 
            -
                   | 
| 348 | 
            -
             | 
| 349 | 
            -
                   | 
| 350 | 
            -
             | 
| 351 | 
            -
                  elsif value.is_a?(Date) || value.is_a?(Time)
         | 
| 352 | 
            -
                    %("#{value.to_s(:db)}")
         | 
| 353 | 
            -
                  else
         | 
| 354 | 
            -
                    value.inspect
         | 
| 355 | 
            -
                  end
         | 
| 285 | 
            +
                  attr_name = attr_name.to_s
         | 
| 286 | 
            +
                  attr_name = self.class.attribute_aliases[attr_name] || attr_name
         | 
| 287 | 
            +
                  value = _read_attribute(attr_name)
         | 
| 288 | 
            +
                  format_for_inspect(attr_name, value)
         | 
| 356 289 | 
             
                end
         | 
| 357 290 |  | 
| 358 291 | 
             
                # Returns +true+ if the specified +attribute+ has been set by the user or by a
         | 
| @@ -370,8 +303,10 @@ module ActiveRecord | |
| 370 303 | 
             
                #   task.is_done = true
         | 
| 371 304 | 
             
                #   task.attribute_present?(:title)   # => true
         | 
| 372 305 | 
             
                #   task.attribute_present?(:is_done) # => true
         | 
| 373 | 
            -
                def attribute_present?( | 
| 374 | 
            -
                   | 
| 306 | 
            +
                def attribute_present?(attr_name)
         | 
| 307 | 
            +
                  attr_name = attr_name.to_s
         | 
| 308 | 
            +
                  attr_name = self.class.attribute_aliases[attr_name] || attr_name
         | 
| 309 | 
            +
                  value = _read_attribute(attr_name)
         | 
| 375 310 | 
             
                  !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
         | 
| 376 311 | 
             
                end
         | 
| 377 312 |  | 
| @@ -443,50 +378,53 @@ module ActiveRecord | |
| 443 378 | 
             
                  @attributes.accessed
         | 
| 444 379 | 
             
                end
         | 
| 445 380 |  | 
| 446 | 
            -
                 | 
| 447 | 
            -
             | 
| 448 | 
            -
                  def attribute_method?(attr_name) # :nodoc:
         | 
| 381 | 
            +
                private
         | 
| 382 | 
            +
                  def attribute_method?(attr_name)
         | 
| 449 383 | 
             
                    # We check defined? because Syck calls respond_to? before actually calling initialize.
         | 
| 450 384 | 
             
                    defined?(@attributes) && @attributes.key?(attr_name)
         | 
| 451 385 | 
             
                  end
         | 
| 452 386 |  | 
| 453 | 
            -
                private
         | 
| 454 | 
            -
             | 
| 455 | 
            -
                  def attributes_with_values_for_create(attribute_names)
         | 
| 456 | 
            -
                    attributes_with_values(attributes_for_create(attribute_names))
         | 
| 457 | 
            -
                  end
         | 
| 458 | 
            -
             | 
| 459 | 
            -
                  def attributes_with_values_for_update(attribute_names)
         | 
| 460 | 
            -
                    attributes_with_values(attributes_for_update(attribute_names))
         | 
| 461 | 
            -
                  end
         | 
| 462 | 
            -
             | 
| 463 387 | 
             
                  def attributes_with_values(attribute_names)
         | 
| 464 | 
            -
                    attribute_names. | 
| 465 | 
            -
                       | 
| 388 | 
            +
                    attribute_names.index_with do |name|
         | 
| 389 | 
            +
                      _read_attribute(name)
         | 
| 466 390 | 
             
                    end
         | 
| 467 391 | 
             
                  end
         | 
| 468 392 |  | 
| 469 393 | 
             
                  # Filters the primary keys and readonly attributes from the attribute names.
         | 
| 470 394 | 
             
                  def attributes_for_update(attribute_names)
         | 
| 471 | 
            -
                    attribute_names | 
| 472 | 
            -
             | 
| 395 | 
            +
                    attribute_names &= self.class.column_names
         | 
| 396 | 
            +
                    attribute_names.delete_if do |name|
         | 
| 397 | 
            +
                      self.class.readonly_attribute?(name)
         | 
| 473 398 | 
             
                    end
         | 
| 474 399 | 
             
                  end
         | 
| 475 400 |  | 
| 476 401 | 
             
                  # Filters out the primary keys, from the attribute names, when the primary
         | 
| 477 402 | 
             
                  # key is to be generated (e.g. the id attribute has no value).
         | 
| 478 403 | 
             
                  def attributes_for_create(attribute_names)
         | 
| 479 | 
            -
                    attribute_names | 
| 404 | 
            +
                    attribute_names &= self.class.column_names
         | 
| 405 | 
            +
                    attribute_names.delete_if do |name|
         | 
| 480 406 | 
             
                      pk_attribute?(name) && id.nil?
         | 
| 481 407 | 
             
                    end
         | 
| 482 408 | 
             
                  end
         | 
| 483 409 |  | 
| 484 | 
            -
                  def  | 
| 485 | 
            -
                     | 
| 410 | 
            +
                  def format_for_inspect(name, value)
         | 
| 411 | 
            +
                    if value.nil?
         | 
| 412 | 
            +
                      value.inspect
         | 
| 413 | 
            +
                    else
         | 
| 414 | 
            +
                      inspected_value = if value.is_a?(String) && value.length > 50
         | 
| 415 | 
            +
                        "#{value[0, 50]}...".inspect
         | 
| 416 | 
            +
                      elsif value.is_a?(Date) || value.is_a?(Time)
         | 
| 417 | 
            +
                        %("#{value.to_s(:inspect)}")
         | 
| 418 | 
            +
                      else
         | 
| 419 | 
            +
                        value.inspect
         | 
| 420 | 
            +
                      end
         | 
| 421 | 
            +
             | 
| 422 | 
            +
                      inspection_filter.filter_param(name, inspected_value)
         | 
| 423 | 
            +
                    end
         | 
| 486 424 | 
             
                  end
         | 
| 487 425 |  | 
| 488 426 | 
             
                  def pk_attribute?(name)
         | 
| 489 | 
            -
                    name ==  | 
| 427 | 
            +
                    name == @primary_key
         | 
| 490 428 | 
             
                  end
         | 
| 491 429 | 
             
              end
         | 
| 492 430 | 
             
            end
         | 
| @@ -12,6 +12,9 @@ module ActiveRecord | |
| 12 12 | 
             
                end
         | 
| 13 13 |  | 
| 14 14 | 
             
                module ClassMethods
         | 
| 15 | 
            +
                  ##
         | 
| 16 | 
            +
                  # :call-seq: attribute(name, cast_type = nil, **options)
         | 
| 17 | 
            +
                  #
         | 
| 15 18 | 
             
                  # Defines an attribute with a type on this model. It will override the
         | 
| 16 19 | 
             
                  # type of existing attributes if needed. This allows control over how
         | 
| 17 20 | 
             
                  # values are converted to and from SQL when assigned to a model. It also
         | 
| @@ -41,6 +44,9 @@ module ActiveRecord | |
| 41 44 | 
             
                  # +range+ (PostgreSQL only) specifies that the type should be a range (see the
         | 
| 42 45 | 
             
                  # examples below).
         | 
| 43 46 | 
             
                  #
         | 
| 47 | 
            +
                  # When using a symbol for +cast_type+, extra options are forwarded to the
         | 
| 48 | 
            +
                  # constructor of the type object.
         | 
| 49 | 
            +
                  #
         | 
| 44 50 | 
             
                  # ==== Examples
         | 
| 45 51 | 
             
                  #
         | 
| 46 52 | 
             
                  # The type detected by Active Record can be overridden.
         | 
| @@ -112,6 +118,16 @@ module ActiveRecord | |
| 112 118 | 
             
                  #       my_float_range: 1.0..3.5
         | 
| 113 119 | 
             
                  #     }
         | 
| 114 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 | 
            +
                  #
         | 
| 115 131 | 
             
                  # ==== Creating Custom Types
         | 
| 116 132 | 
             
                  #
         | 
| 117 133 | 
             
                  # Users may also define their own custom types, as long as they respond
         | 
| @@ -192,13 +208,13 @@ module ActiveRecord | |
| 192 208 | 
             
                  # tracking is performed. The methods +changed?+ and +changed_in_place?+
         | 
| 193 209 | 
             
                  # will be called from ActiveModel::Dirty. See the documentation for those
         | 
| 194 210 | 
             
                  # methods in ActiveModel::Type::Value for more details.
         | 
| 195 | 
            -
                  def attribute(name, cast_type =  | 
| 211 | 
            +
                  def attribute(name, cast_type = nil, **options, &block)
         | 
| 196 212 | 
             
                    name = name.to_s
         | 
| 197 213 | 
             
                    reload_schema_from_cache
         | 
| 198 214 |  | 
| 199 215 | 
             
                    self.attributes_to_define_after_schema_loads =
         | 
| 200 216 | 
             
                      attributes_to_define_after_schema_loads.merge(
         | 
| 201 | 
            -
                        name => [cast_type, options]
         | 
| 217 | 
            +
                        name => [cast_type || block, options]
         | 
| 202 218 | 
             
                      )
         | 
| 203 219 | 
             
                  end
         | 
| 204 220 |  | 
| @@ -233,16 +249,11 @@ module ActiveRecord | |
| 233 249 | 
             
                  def load_schema! # :nodoc:
         | 
| 234 250 | 
             
                    super
         | 
| 235 251 | 
             
                    attributes_to_define_after_schema_loads.each do |name, (type, options)|
         | 
| 236 | 
            -
                       | 
| 237 | 
            -
                        type = ActiveRecord::Type.lookup(type, **options.except(:default))
         | 
| 238 | 
            -
                      end
         | 
| 239 | 
            -
             | 
| 240 | 
            -
                      define_attribute(name, type, **options.slice(:default))
         | 
| 252 | 
            +
                      define_attribute(name, _lookup_cast_type(name, type, options), **options.slice(:default))
         | 
| 241 253 | 
             
                    end
         | 
| 242 254 | 
             
                  end
         | 
| 243 255 |  | 
| 244 256 | 
             
                  private
         | 
| 245 | 
            -
             | 
| 246 257 | 
             
                    NO_DEFAULT_PROVIDED = Object.new # :nodoc:
         | 
| 247 258 | 
             
                    private_constant :NO_DEFAULT_PROVIDED
         | 
| 248 259 |  | 
| @@ -261,6 +272,32 @@ module ActiveRecord | |
| 261 272 | 
             
                      end
         | 
| 262 273 | 
             
                      _default_attributes[name] = default_attribute
         | 
| 263 274 | 
             
                    end
         | 
| 275 | 
            +
             | 
| 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
         | 
| 300 | 
            +
                    end
         | 
| 264 301 | 
             
                end
         | 
| 265 302 | 
             
              end
         | 
| 266 303 | 
             
            end
         |