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
| @@ -10,9 +10,6 @@ module ActiveRecord | |
| 10 10 | 
             
                included do
         | 
| 11 11 | 
             
                  define_callbacks :commit, :rollback,
         | 
| 12 12 | 
             
                                   :before_commit,
         | 
| 13 | 
            -
                                   :before_commit_without_transaction_enrollment,
         | 
| 14 | 
            -
                                   :commit_without_transaction_enrollment,
         | 
| 15 | 
            -
                                   :rollback_without_transaction_enrollment,
         | 
| 16 13 | 
             
                                   scope: [:kind, :name]
         | 
| 17 14 | 
             
                end
         | 
| 18 15 |  | 
| @@ -164,13 +161,13 @@ module ActiveRecord | |
| 164 161 | 
             
                #     end
         | 
| 165 162 | 
             
                #   end
         | 
| 166 163 | 
             
                #
         | 
| 167 | 
            -
                # only "Kotori" is created. | 
| 164 | 
            +
                # only "Kotori" is created.
         | 
| 168 165 | 
             
                #
         | 
| 169 166 | 
             
                # Most databases don't support true nested transactions. At the time of
         | 
| 170 167 | 
             
                # writing, the only database that we're aware of that supports true nested
         | 
| 171 168 | 
             
                # transactions, is MS-SQL. Because of this, Active Record emulates nested
         | 
| 172 | 
            -
                # transactions by using savepoints | 
| 173 | 
            -
                # https://dev.mysql.com/doc/refman/ | 
| 169 | 
            +
                # transactions by using savepoints. See
         | 
| 170 | 
            +
                # https://dev.mysql.com/doc/refman/en/savepoint.html
         | 
| 174 171 | 
             
                # for more information about savepoints.
         | 
| 175 172 | 
             
                #
         | 
| 176 173 | 
             
                # === \Callbacks
         | 
| @@ -208,8 +205,8 @@ module ActiveRecord | |
| 208 205 | 
             
                # Note that "TRUNCATE" is also a MySQL DDL statement!
         | 
| 209 206 | 
             
                module ClassMethods
         | 
| 210 207 | 
             
                  # See the ConnectionAdapters::DatabaseStatements#transaction API docs.
         | 
| 211 | 
            -
                  def transaction(options | 
| 212 | 
            -
                    connection.transaction(options, &block)
         | 
| 208 | 
            +
                  def transaction(**options, &block)
         | 
| 209 | 
            +
                    connection.transaction(**options, &block)
         | 
| 213 210 | 
             
                  end
         | 
| 214 211 |  | 
| 215 212 | 
             
                  def before_commit(*args, &block) # :nodoc:
         | 
| @@ -234,6 +231,12 @@ module ActiveRecord | |
| 234 231 | 
             
                    set_callback(:commit, :after, *args, &block)
         | 
| 235 232 | 
             
                  end
         | 
| 236 233 |  | 
| 234 | 
            +
                  # Shortcut for <tt>after_commit :hook, on: [ :create, :update ]</tt>.
         | 
| 235 | 
            +
                  def after_save_commit(*args, &block)
         | 
| 236 | 
            +
                    set_options_for_callbacks!(args, on: [ :create, :update ])
         | 
| 237 | 
            +
                    set_callback(:commit, :after, *args, &block)
         | 
| 238 | 
            +
                  end
         | 
| 239 | 
            +
             | 
| 237 240 | 
             
                  # Shortcut for <tt>after_commit :hook, on: :create</tt>.
         | 
| 238 241 | 
             
                  def after_create_commit(*args, &block)
         | 
| 239 242 | 
             
                    set_options_for_callbacks!(args, on: :create)
         | 
| @@ -260,23 +263,7 @@ module ActiveRecord | |
| 260 263 | 
             
                    set_callback(:rollback, :after, *args, &block)
         | 
| 261 264 | 
             
                  end
         | 
| 262 265 |  | 
| 263 | 
            -
                  def before_commit_without_transaction_enrollment(*args, &block) # :nodoc:
         | 
| 264 | 
            -
                    set_options_for_callbacks!(args)
         | 
| 265 | 
            -
                    set_callback(:before_commit_without_transaction_enrollment, :before, *args, &block)
         | 
| 266 | 
            -
                  end
         | 
| 267 | 
            -
             | 
| 268 | 
            -
                  def after_commit_without_transaction_enrollment(*args, &block) # :nodoc:
         | 
| 269 | 
            -
                    set_options_for_callbacks!(args)
         | 
| 270 | 
            -
                    set_callback(:commit_without_transaction_enrollment, :after, *args, &block)
         | 
| 271 | 
            -
                  end
         | 
| 272 | 
            -
             | 
| 273 | 
            -
                  def after_rollback_without_transaction_enrollment(*args, &block) # :nodoc:
         | 
| 274 | 
            -
                    set_options_for_callbacks!(args)
         | 
| 275 | 
            -
                    set_callback(:rollback_without_transaction_enrollment, :after, *args, &block)
         | 
| 276 | 
            -
                  end
         | 
| 277 | 
            -
             | 
| 278 266 | 
             
                  private
         | 
| 279 | 
            -
             | 
| 280 267 | 
             
                    def set_options_for_callbacks!(args, enforced_options = {})
         | 
| 281 268 | 
             
                      options = args.extract_options!.merge!(enforced_options)
         | 
| 282 269 | 
             
                      args << options
         | 
| @@ -297,41 +284,27 @@ module ActiveRecord | |
| 297 284 | 
             
                end
         | 
| 298 285 |  | 
| 299 286 | 
             
                # See ActiveRecord::Transactions::ClassMethods for detailed documentation.
         | 
| 300 | 
            -
                def transaction(options | 
| 301 | 
            -
                  self.class.transaction(options, &block)
         | 
| 287 | 
            +
                def transaction(**options, &block)
         | 
| 288 | 
            +
                  self.class.transaction(**options, &block)
         | 
| 302 289 | 
             
                end
         | 
| 303 290 |  | 
| 304 291 | 
             
                def destroy #:nodoc:
         | 
| 305 292 | 
             
                  with_transaction_returning_status { super }
         | 
| 306 293 | 
             
                end
         | 
| 307 294 |  | 
| 308 | 
            -
                def save( | 
| 309 | 
            -
                  rollback_active_record_state! do
         | 
| 310 | 
            -
                    with_transaction_returning_status { super }
         | 
| 311 | 
            -
                  end
         | 
| 312 | 
            -
                end
         | 
| 313 | 
            -
             | 
| 314 | 
            -
                def save!(*) #:nodoc:
         | 
| 295 | 
            +
                def save(**) #:nodoc:
         | 
| 315 296 | 
             
                  with_transaction_returning_status { super }
         | 
| 316 297 | 
             
                end
         | 
| 317 298 |  | 
| 318 | 
            -
                def  | 
| 299 | 
            +
                def save!(**) #:nodoc:
         | 
| 319 300 | 
             
                  with_transaction_returning_status { super }
         | 
| 320 301 | 
             
                end
         | 
| 321 302 |  | 
| 322 | 
            -
                 | 
| 323 | 
            -
             | 
| 324 | 
            -
                  remember_transaction_record_state
         | 
| 325 | 
            -
                  yield
         | 
| 326 | 
            -
                rescue Exception
         | 
| 327 | 
            -
                  restore_transaction_record_state
         | 
| 328 | 
            -
                  raise
         | 
| 329 | 
            -
                ensure
         | 
| 330 | 
            -
                  clear_transaction_record_state
         | 
| 303 | 
            +
                def touch(*, **) #:nodoc:
         | 
| 304 | 
            +
                  with_transaction_returning_status { super }
         | 
| 331 305 | 
             
                end
         | 
| 332 306 |  | 
| 333 307 | 
             
                def before_committed! # :nodoc:
         | 
| 334 | 
            -
                  _run_before_commit_without_transaction_enrollment_callbacks
         | 
| 335 308 | 
             
                  _run_before_commit_callbacks
         | 
| 336 309 | 
             
                end
         | 
| 337 310 |  | 
| @@ -340,14 +313,13 @@ module ActiveRecord | |
| 340 313 | 
             
                # Ensure that it is not called if the object was never persisted (failed create),
         | 
| 341 314 | 
             
                # but call it after the commit of a destroyed object.
         | 
| 342 315 | 
             
                def committed!(should_run_callbacks: true) #:nodoc:
         | 
| 343 | 
            -
                   | 
| 316 | 
            +
                  force_clear_transaction_record_state
         | 
| 317 | 
            +
                  if should_run_callbacks
         | 
| 344 318 | 
             
                    @_committed_already_called = true
         | 
| 345 | 
            -
                    _run_commit_without_transaction_enrollment_callbacks
         | 
| 346 319 | 
             
                    _run_commit_callbacks
         | 
| 347 320 | 
             
                  end
         | 
| 348 321 | 
             
                ensure
         | 
| 349 | 
            -
                  @_committed_already_called = false
         | 
| 350 | 
            -
                  force_clear_transaction_record_state
         | 
| 322 | 
            +
                  @_committed_already_called = @_trigger_update_callback = @_trigger_destroy_callback = false
         | 
| 351 323 | 
             
                end
         | 
| 352 324 |  | 
| 353 325 | 
             
                # Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
         | 
| @@ -355,23 +327,11 @@ module ActiveRecord | |
| 355 327 | 
             
                def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
         | 
| 356 328 | 
             
                  if should_run_callbacks
         | 
| 357 329 | 
             
                    _run_rollback_callbacks
         | 
| 358 | 
            -
                    _run_rollback_without_transaction_enrollment_callbacks
         | 
| 359 330 | 
             
                  end
         | 
| 360 331 | 
             
                ensure
         | 
| 361 332 | 
             
                  restore_transaction_record_state(force_restore_state)
         | 
| 362 333 | 
             
                  clear_transaction_record_state
         | 
| 363 | 
            -
             | 
| 364 | 
            -
             | 
| 365 | 
            -
                # Add the record to the current transaction so that the #after_rollback and #after_commit callbacks
         | 
| 366 | 
            -
                # can be called.
         | 
| 367 | 
            -
                def add_to_transaction
         | 
| 368 | 
            -
                  if has_transactional_callbacks?
         | 
| 369 | 
            -
                    self.class.connection.add_transaction_record(self)
         | 
| 370 | 
            -
                  else
         | 
| 371 | 
            -
                    sync_with_transaction_state
         | 
| 372 | 
            -
                    set_transaction_state(self.class.connection.transaction_state)
         | 
| 373 | 
            -
                  end
         | 
| 374 | 
            -
                  remember_transaction_record_state
         | 
| 334 | 
            +
                  @_trigger_update_callback = @_trigger_destroy_callback = false if force_restore_state
         | 
| 375 335 | 
             
                end
         | 
| 376 336 |  | 
| 377 337 | 
             
                # Executes +method+ within a transaction and captures its return value as a
         | 
| @@ -382,36 +342,40 @@ module ActiveRecord | |
| 382 342 | 
             
                # instance.
         | 
| 383 343 | 
             
                def with_transaction_returning_status
         | 
| 384 344 | 
             
                  status = nil
         | 
| 385 | 
            -
                  self.class. | 
| 386 | 
            -
             | 
| 345 | 
            +
                  connection = self.class.connection
         | 
| 346 | 
            +
                  ensure_finalize = !connection.transaction_open?
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                  connection.transaction do
         | 
| 349 | 
            +
                    add_to_transaction(ensure_finalize || has_transactional_callbacks?)
         | 
| 350 | 
            +
                    remember_transaction_record_state
         | 
| 351 | 
            +
             | 
| 387 352 | 
             
                    status = yield
         | 
| 388 353 | 
             
                    raise ActiveRecord::Rollback unless status
         | 
| 389 354 | 
             
                  end
         | 
| 390 355 | 
             
                  status
         | 
| 391 | 
            -
                ensure
         | 
| 392 | 
            -
                  if @transaction_state && @transaction_state.committed?
         | 
| 393 | 
            -
                    clear_transaction_record_state
         | 
| 394 | 
            -
                  end
         | 
| 395 356 | 
             
                end
         | 
| 396 357 |  | 
| 397 | 
            -
                 | 
| 398 | 
            -
                   | 
| 358 | 
            +
                def trigger_transactional_callbacks? # :nodoc:
         | 
| 359 | 
            +
                  (@_new_record_before_last_commit || _trigger_update_callback) && persisted? ||
         | 
| 360 | 
            +
                    _trigger_destroy_callback && destroyed?
         | 
| 361 | 
            +
                end
         | 
| 399 362 |  | 
| 400 363 | 
             
                private
         | 
| 364 | 
            +
                  attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
         | 
| 401 365 |  | 
| 402 366 | 
             
                  # Save the new record state and id of a record so it can be restored later if a transaction fails.
         | 
| 403 367 | 
             
                  def remember_transaction_record_state
         | 
| 404 | 
            -
                    @_start_transaction_state | 
| 368 | 
            +
                    @_start_transaction_state ||= {
         | 
| 405 369 | 
             
                      id: id,
         | 
| 406 370 | 
             
                      new_record: @new_record,
         | 
| 371 | 
            +
                      previously_new_record: @previously_new_record,
         | 
| 407 372 | 
             
                      destroyed: @destroyed,
         | 
| 373 | 
            +
                      attributes: @attributes,
         | 
| 408 374 | 
             
                      frozen?: frozen?,
         | 
| 409 | 
            -
             | 
| 410 | 
            -
                     | 
| 411 | 
            -
                     | 
| 412 | 
            -
                  end
         | 
| 375 | 
            +
                      level: 0
         | 
| 376 | 
            +
                    }
         | 
| 377 | 
            +
                    @_start_transaction_state[:level] += 1
         | 
| 413 378 |  | 
| 414 | 
            -
                  def remember_new_record_before_last_commit
         | 
| 415 379 | 
             
                    if _committed_already_called
         | 
| 416 380 | 
             
                      @_new_record_before_last_commit = false
         | 
| 417 381 | 
             
                    else
         | 
| @@ -421,27 +385,32 @@ module ActiveRecord | |
| 421 385 |  | 
| 422 386 | 
             
                  # Clear the new record state and id of a record.
         | 
| 423 387 | 
             
                  def clear_transaction_record_state
         | 
| 424 | 
            -
                     | 
| 388 | 
            +
                    return unless @_start_transaction_state
         | 
| 389 | 
            +
                    @_start_transaction_state[:level] -= 1
         | 
| 425 390 | 
             
                    force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
         | 
| 426 391 | 
             
                  end
         | 
| 427 392 |  | 
| 428 393 | 
             
                  # Force to clear the transaction record state.
         | 
| 429 394 | 
             
                  def force_clear_transaction_record_state
         | 
| 430 | 
            -
                    @_start_transaction_state | 
| 395 | 
            +
                    @_start_transaction_state = nil
         | 
| 431 396 | 
             
                  end
         | 
| 432 397 |  | 
| 433 398 | 
             
                  # Restore the new record state and id of a record that was previously saved by a call to save_record_state.
         | 
| 434 | 
            -
                  def restore_transaction_record_state( | 
| 435 | 
            -
                     | 
| 436 | 
            -
                       | 
| 437 | 
            -
                      if transaction_level < 1 || force
         | 
| 438 | 
            -
                        restore_state = @_start_transaction_state
         | 
| 439 | 
            -
                        thaw
         | 
| 399 | 
            +
                  def restore_transaction_record_state(force_restore_state = false)
         | 
| 400 | 
            +
                    if restore_state = @_start_transaction_state
         | 
| 401 | 
            +
                      if force_restore_state || restore_state[:level] <= 1
         | 
| 440 402 | 
             
                        @new_record = restore_state[:new_record]
         | 
| 403 | 
            +
                        @previously_new_record = restore_state[:previously_new_record]
         | 
| 441 404 | 
             
                        @destroyed  = restore_state[:destroyed]
         | 
| 442 | 
            -
                         | 
| 443 | 
            -
             | 
| 444 | 
            -
                           | 
| 405 | 
            +
                        @attributes = restore_state[:attributes].map do |attr|
         | 
| 406 | 
            +
                          value = @attributes.fetch_value(attr.name)
         | 
| 407 | 
            +
                          attr = attr.with_value_from_user(value) if attr.value != value
         | 
| 408 | 
            +
                          attr
         | 
| 409 | 
            +
                        end
         | 
| 410 | 
            +
                        @mutations_from_database = nil
         | 
| 411 | 
            +
                        @mutations_before_last_save = nil
         | 
| 412 | 
            +
                        if @attributes.fetch_value(@primary_key) != restore_state[:id]
         | 
| 413 | 
            +
                          @attributes.write_from_user(@primary_key, restore_state[:id])
         | 
| 445 414 | 
             
                        end
         | 
| 446 415 | 
             
                        freeze if restore_state[:frozen?]
         | 
| 447 416 | 
             
                      end
         | 
| @@ -462,41 +431,14 @@ module ActiveRecord | |
| 462 431 | 
             
                    end
         | 
| 463 432 | 
             
                  end
         | 
| 464 433 |  | 
| 465 | 
            -
                   | 
| 466 | 
            -
             | 
| 434 | 
            +
                  # Add the record to the current transaction so that the #after_rollback and #after_commit
         | 
| 435 | 
            +
                  # callbacks can be called.
         | 
| 436 | 
            +
                  def add_to_transaction(ensure_finalize = true)
         | 
| 437 | 
            +
                    self.class.connection.add_transaction_record(self, ensure_finalize)
         | 
| 467 438 | 
             
                  end
         | 
| 468 439 |  | 
| 469 440 | 
             
                  def has_transactional_callbacks?
         | 
| 470 441 | 
             
                    !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
         | 
| 471 442 | 
             
                  end
         | 
| 472 | 
            -
             | 
| 473 | 
            -
                  # Updates the attributes on this particular Active Record object so that
         | 
| 474 | 
            -
                  # if it's associated with a transaction, then the state of the Active Record
         | 
| 475 | 
            -
                  # object will be updated to reflect the current state of the transaction.
         | 
| 476 | 
            -
                  #
         | 
| 477 | 
            -
                  # The <tt>@transaction_state</tt> variable stores the states of the associated
         | 
| 478 | 
            -
                  # transaction. This relies on the fact that a transaction can only be in
         | 
| 479 | 
            -
                  # one rollback or commit (otherwise a list of states would be required).
         | 
| 480 | 
            -
                  # Each Active Record object inside of a transaction carries that transaction's
         | 
| 481 | 
            -
                  # TransactionState.
         | 
| 482 | 
            -
                  #
         | 
| 483 | 
            -
                  # This method checks to see if the ActiveRecord object's state reflects
         | 
| 484 | 
            -
                  # the TransactionState, and rolls back or commits the Active Record object
         | 
| 485 | 
            -
                  # as appropriate.
         | 
| 486 | 
            -
                  #
         | 
| 487 | 
            -
                  # Since Active Record objects can be inside multiple transactions, this
         | 
| 488 | 
            -
                  # method recursively goes through the parent of the TransactionState and
         | 
| 489 | 
            -
                  # checks if the Active Record object reflects the state of the object.
         | 
| 490 | 
            -
                  def sync_with_transaction_state
         | 
| 491 | 
            -
                    update_attributes_from_transaction_state(@transaction_state)
         | 
| 492 | 
            -
                  end
         | 
| 493 | 
            -
             | 
| 494 | 
            -
                  def update_attributes_from_transaction_state(transaction_state)
         | 
| 495 | 
            -
                    if transaction_state && transaction_state.finalized?
         | 
| 496 | 
            -
                      restore_transaction_record_state(transaction_state.fully_rolledback?) if transaction_state.rolledback?
         | 
| 497 | 
            -
                      force_clear_transaction_record_state if transaction_state.fully_committed?
         | 
| 498 | 
            -
                      clear_transaction_record_state if transaction_state.fully_completed?
         | 
| 499 | 
            -
                    end
         | 
| 500 | 
            -
                  end
         | 
| 501 443 | 
             
              end
         | 
| 502 444 | 
             
            end
         | 
| @@ -11,14 +11,13 @@ module ActiveRecord | |
| 11 11 | 
             
                  end
         | 
| 12 12 |  | 
| 13 13 | 
             
                  private
         | 
| 14 | 
            -
             | 
| 15 14 | 
             
                    def registration_klass
         | 
| 16 15 | 
             
                      Registration
         | 
| 17 16 | 
             
                    end
         | 
| 18 17 |  | 
| 19 | 
            -
                    def find_registration(symbol, *args)
         | 
| 18 | 
            +
                    def find_registration(symbol, *args, **kwargs)
         | 
| 20 19 | 
             
                      registrations
         | 
| 21 | 
            -
                        .select { |registration| registration.matches?(symbol, *args) }
         | 
| 20 | 
            +
                        .select { |registration| registration.matches?(symbol, *args, **kwargs) }
         | 
| 22 21 | 
             
                        .max
         | 
| 23 22 | 
             
                    end
         | 
| 24 23 | 
             
                end
         | 
| @@ -52,10 +51,7 @@ module ActiveRecord | |
| 52 51 | 
             
                    priority <=> other.priority
         | 
| 53 52 | 
             
                  end
         | 
| 54 53 |  | 
| 55 | 
            -
                  # TODO Change this to private once we've dropped Ruby 2.2 support.
         | 
| 56 | 
            -
                  # Workaround for Ruby 2.2 "private attribute?" warning.
         | 
| 57 54 | 
             
                  protected
         | 
| 58 | 
            -
             | 
| 59 55 | 
             
                    attr_reader :name, :block, :adapter, :override
         | 
| 60 56 |  | 
| 61 57 | 
             
                    def priority
         | 
| @@ -74,7 +70,6 @@ module ActiveRecord | |
| 74 70 | 
             
                    end
         | 
| 75 71 |  | 
| 76 72 | 
             
                  private
         | 
| 77 | 
            -
             | 
| 78 73 | 
             
                    def matches_adapter?(adapter: nil, **)
         | 
| 79 74 | 
             
                      (self.adapter.nil? || adapter == self.adapter)
         | 
| 80 75 | 
             
                    end
         | 
| @@ -114,13 +109,8 @@ module ActiveRecord | |
| 114 109 | 
             
                    super | 4
         | 
| 115 110 | 
             
                  end
         | 
| 116 111 |  | 
| 117 | 
            -
                  # TODO Change this to private once we've dropped Ruby 2.2 support.
         | 
| 118 | 
            -
                  # Workaround for Ruby 2.2 "private attribute?" warning.
         | 
| 119 | 
            -
                  protected
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                    attr_reader :options, :klass
         | 
| 122 | 
            -
             | 
| 123 112 | 
             
                  private
         | 
| 113 | 
            +
                    attr_reader :options, :klass
         | 
| 124 114 |  | 
| 125 115 | 
             
                    def matches_options?(**kwargs)
         | 
| 126 116 | 
             
                      options.all? do |key, value|
         | 
| @@ -56,15 +56,18 @@ module ActiveRecord | |
| 56 56 | 
             
                  end
         | 
| 57 57 |  | 
| 58 58 | 
             
                  private
         | 
| 59 | 
            -
             | 
| 60 59 | 
             
                    def default_value?(value)
         | 
| 61 60 | 
             
                      value == coder.load(nil)
         | 
| 62 61 | 
             
                    end
         | 
| 63 62 |  | 
| 64 63 | 
             
                    def encoded(value)
         | 
| 65 | 
            -
                       | 
| 66 | 
            -
             | 
| 64 | 
            +
                      return if default_value?(value)
         | 
| 65 | 
            +
                      payload = coder.dump(value)
         | 
| 66 | 
            +
                      if payload && binary? && payload.encoding != Encoding::BINARY
         | 
| 67 | 
            +
                        payload = payload.dup if payload.frozen?
         | 
| 68 | 
            +
                        payload.force_encoding(Encoding::BINARY)
         | 
| 67 69 | 
             
                      end
         | 
| 70 | 
            +
                      payload
         | 
| 68 71 | 
             
                    end
         | 
| 69 72 | 
             
                end
         | 
| 70 73 | 
             
              end
         | 
    
        data/lib/active_record/type.rb
    CHANGED
    
    | @@ -46,20 +46,24 @@ module ActiveRecord | |
| 46 46 | 
             
                    @default_value ||= Value.new
         | 
| 47 47 | 
             
                  end
         | 
| 48 48 |  | 
| 49 | 
            -
                   | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
                    ActiveRecord::Base.connection.adapter_name.downcase.to_sym
         | 
| 49 | 
            +
                  def adapter_name_from(model) # :nodoc:
         | 
| 50 | 
            +
                    # TODO: this shouldn't depend on a connection to the database
         | 
| 51 | 
            +
                    model.connection.adapter_name.downcase.to_sym
         | 
| 53 52 | 
             
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  private
         | 
| 55 | 
            +
                    def current_adapter_name
         | 
| 56 | 
            +
                      adapter_name_from(ActiveRecord::Base)
         | 
| 57 | 
            +
                    end
         | 
| 54 58 | 
             
                end
         | 
| 55 59 |  | 
| 56 | 
            -
                Helpers = ActiveModel::Type::Helpers
         | 
| 57 60 | 
             
                BigInteger = ActiveModel::Type::BigInteger
         | 
| 58 61 | 
             
                Binary = ActiveModel::Type::Binary
         | 
| 59 62 | 
             
                Boolean = ActiveModel::Type::Boolean
         | 
| 60 63 | 
             
                Decimal = ActiveModel::Type::Decimal
         | 
| 61 64 | 
             
                Float = ActiveModel::Type::Float
         | 
| 62 65 | 
             
                Integer = ActiveModel::Type::Integer
         | 
| 66 | 
            +
                ImmutableString = ActiveModel::Type::ImmutableString
         | 
| 63 67 | 
             
                String = ActiveModel::Type::String
         | 
| 64 68 | 
             
                Value = ActiveModel::Type::Value
         | 
| 65 69 |  | 
| @@ -71,6 +75,7 @@ module ActiveRecord | |
| 71 75 | 
             
                register(:decimal, Type::Decimal, override: false)
         | 
| 72 76 | 
             
                register(:float, Type::Float, override: false)
         | 
| 73 77 | 
             
                register(:integer, Type::Integer, override: false)
         | 
| 78 | 
            +
                register(:immutable_string, Type::ImmutableString, override: false)
         | 
| 74 79 | 
             
                register(:json, Type::Json, override: false)
         | 
| 75 80 | 
             
                register(:string, Type::String, override: false)
         | 
| 76 81 | 
             
                register(:text, Type::Text, override: false)
         | 
| @@ -8,26 +8,26 @@ module ActiveRecord | |
| 8 8 | 
             
                    @table_name = table_name
         | 
| 9 9 | 
             
                  end
         | 
| 10 10 |  | 
| 11 | 
            -
                  def type_cast_for_database( | 
| 12 | 
            -
                     | 
| 13 | 
            -
                     | 
| 14 | 
            -
                    connection.type_cast_from_column(column, value)
         | 
| 11 | 
            +
                  def type_cast_for_database(attr_name, value)
         | 
| 12 | 
            +
                    type = type_for_attribute(attr_name)
         | 
| 13 | 
            +
                    type.serialize(value)
         | 
| 15 14 | 
             
                  end
         | 
| 16 15 |  | 
| 17 | 
            -
                   | 
| 18 | 
            -
             | 
| 19 | 
            -
                  protected
         | 
| 16 | 
            +
                  def type_for_attribute(attr_name)
         | 
| 17 | 
            +
                    schema_cache = connection.schema_cache
         | 
| 20 18 |  | 
| 21 | 
            -
                     | 
| 22 | 
            -
             | 
| 19 | 
            +
                    if schema_cache.data_source_exists?(table_name)
         | 
| 20 | 
            +
                      column = schema_cache.columns_hash(table_name)[attr_name.to_s]
         | 
| 21 | 
            +
                      type = connection.lookup_cast_type_from_column(column) if column
         | 
| 22 | 
            +
                    end
         | 
| 23 23 |  | 
| 24 | 
            -
             | 
| 24 | 
            +
                    type || Type.default_value
         | 
| 25 | 
            +
                  end
         | 
| 25 26 |  | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
                    end
         | 
| 27 | 
            +
                  delegate :connection, to: :@klass, private: true
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  private
         | 
| 30 | 
            +
                    attr_reader :table_name
         | 
| 31 31 | 
             
                end
         | 
| 32 32 | 
             
              end
         | 
| 33 33 | 
             
            end
         | 
| @@ -3,21 +3,21 @@ | |
| 3 3 | 
             
            module ActiveRecord
         | 
| 4 4 | 
             
              module TypeCaster
         | 
| 5 5 | 
             
                class Map # :nodoc:
         | 
| 6 | 
            -
                  def initialize( | 
| 7 | 
            -
                    @ | 
| 6 | 
            +
                  def initialize(klass)
         | 
| 7 | 
            +
                    @klass = klass
         | 
| 8 8 | 
             
                  end
         | 
| 9 9 |  | 
| 10 10 | 
             
                  def type_cast_for_database(attr_name, value)
         | 
| 11 | 
            -
                     | 
| 12 | 
            -
                    type = types.type_for_attribute(attr_name)
         | 
| 11 | 
            +
                    type = type_for_attribute(attr_name)
         | 
| 13 12 | 
             
                    type.serialize(value)
         | 
| 14 13 | 
             
                  end
         | 
| 15 14 |  | 
| 16 | 
            -
                   | 
| 17 | 
            -
             | 
| 18 | 
            -
                   | 
| 15 | 
            +
                  def type_for_attribute(name)
         | 
| 16 | 
            +
                    klass.type_for_attribute(name)
         | 
| 17 | 
            +
                  end
         | 
| 19 18 |  | 
| 20 | 
            -
             | 
| 19 | 
            +
                  private
         | 
| 20 | 
            +
                    attr_reader :klass
         | 
| 21 21 | 
             
                end
         | 
| 22 22 | 
             
              end
         | 
| 23 23 | 
             
            end
         | 
| @@ -5,12 +5,11 @@ module ActiveRecord | |
| 5 5 | 
             
                class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
         | 
| 6 6 | 
             
                  def validate_each(record, attribute, value)
         | 
| 7 7 | 
             
                    if Array(value).reject { |r| valid_object?(r) }.any?
         | 
| 8 | 
            -
                      record.errors.add(attribute, :invalid, options.merge(value: value))
         | 
| 8 | 
            +
                      record.errors.add(attribute, :invalid, **options.merge(value: value))
         | 
| 9 9 | 
             
                    end
         | 
| 10 10 | 
             
                  end
         | 
| 11 11 |  | 
| 12 12 | 
             
                  private
         | 
| 13 | 
            -
             | 
| 14 13 | 
             
                    def valid_object?(record)
         | 
| 15 14 | 
             
                      (record.respond_to?(:marked_for_destruction?) && record.marked_for_destruction?) || record.valid?
         | 
| 16 15 | 
             
                    end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ActiveRecord
         | 
| 4 | 
            +
              module Validations
         | 
| 5 | 
            +
                class NumericalityValidator < ActiveModel::Validations::NumericalityValidator # :nodoc:
         | 
| 6 | 
            +
                  def validate_each(record, attribute, value, precision: nil, scale: nil)
         | 
| 7 | 
            +
                    precision = [column_precision_for(record, attribute) || BigDecimal.double_fig, BigDecimal.double_fig].min
         | 
| 8 | 
            +
                    scale     = column_scale_for(record, attribute)
         | 
| 9 | 
            +
                    super(record, attribute, value, precision: precision, scale: scale)
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  private
         | 
| 13 | 
            +
                    def column_precision_for(record, attribute)
         | 
| 14 | 
            +
                      record.class.type_for_attribute(attribute.to_s)&.precision
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    def column_scale_for(record, attribute)
         | 
| 18 | 
            +
                      record.class.type_for_attribute(attribute.to_s)&.scale
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                module ClassMethods
         | 
| 23 | 
            +
                  # Validates whether the value of the specified attribute is numeric by
         | 
| 24 | 
            +
                  # trying to convert it to a float with Kernel.Float (if <tt>only_integer</tt>
         | 
| 25 | 
            +
                  # is +false+) or applying it to the regular expression <tt>/\A[\+\-]?\d+\z/</tt>
         | 
| 26 | 
            +
                  # (if <tt>only_integer</tt> is set to +true+). Kernel.Float precision
         | 
| 27 | 
            +
                  # defaults to the column's precision value or 15.
         | 
| 28 | 
            +
                  #
         | 
| 29 | 
            +
                  # See ActiveModel::Validations::HelperMethods.validates_numericality_of for more information.
         | 
| 30 | 
            +
                  def validates_numericality_of(*attr_names)
         | 
| 31 | 
            +
                    validates_with NumericalityValidator, _merge_attributes(attr_names)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         |