activerecord 5.2.8.1 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +849 -630
- 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 +8 -17
- 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 +24 -18
- 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 +41 -20
- 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 +47 -34
- 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 +57 -42
- data/lib/active_record/base.rb +4 -17
- data/lib/active_record/callbacks.rb +158 -43
- data/lib/active_record/coders/yaml_column.rb +2 -15
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
- 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 +18 -14
- 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 +174 -186
- 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 +304 -106
- 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 +4 -4
- 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 +113 -74
- 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 +109 -93
- 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 +153 -90
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +64 -39
- 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 +472 -186
- 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 +4 -6
- 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 +49 -6
- 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 +58 -116
- 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 +120 -35
- 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
|
|
@@ -341,13 +314,12 @@ module ActiveRecord
|
|
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
|
344
|
-
if should_run_callbacks
|
317
|
+
if should_run_callbacks
|
345
318
|
@_committed_already_called = true
|
346
|
-
_run_commit_without_transaction_enrollment_callbacks
|
347
319
|
_run_commit_callbacks
|
348
320
|
end
|
349
321
|
ensure
|
350
|
-
@_committed_already_called = false
|
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
|