activerecord 5.2.8.1 → 6.1.6.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1255 -596
- data/MIT-LICENSE +3 -1
- data/README.rdoc +7 -5
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +9 -8
- data/lib/active_record/association_relation.rb +30 -10
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +100 -41
- data/lib/active_record/associations/association_scope.rb +23 -21
- data/lib/active_record/associations/belongs_to_association.rb +55 -48
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
- data/lib/active_record/associations/builder/association.rb +45 -22
- 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 +44 -34
- 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 +44 -22
- 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 +69 -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 +137 -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 +46 -9
- 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 +1 -2
- 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 +211 -90
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
- data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
- data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
- 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 +35 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -32
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -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 +18 -7
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -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 +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -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/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 +224 -120
- data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -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 +52 -0
- data/lib/active_record/connection_handling.rb +293 -33
- data/lib/active_record/core.rb +333 -98
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -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 +273 -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 +108 -36
- 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 +200 -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 +212 -0
- data/lib/active_record/integration.rb +67 -17
- data/lib/active_record/internal_metadata.rb +28 -9
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +37 -23
- data/lib/active_record/locking/pessimistic.rb +9 -5
- data/lib/active_record/log_subscriber.rb +35 -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 +145 -64
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +206 -157
- 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 +116 -59
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +411 -80
- 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 +157 -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 +11 -10
- 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 +62 -45
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +476 -187
- 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 +115 -62
- data/lib/active_record/relation.rb +379 -115
- 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 -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 +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 +42 -43
- data/lib/active_record/tasks/database_tasks.rb +277 -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 +287 -0
- data/lib/active_record/timestamp.rb +43 -32
- data/lib/active_record/touch_later.rb +23 -22
- data/lib/active_record/transactions.rb +62 -118
- 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 +76 -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 +116 -30
- 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
@@ -2,27 +2,26 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
# = Active Record Touch Later
|
5
|
-
module TouchLater
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
before_commit_without_transaction_enrollment :touch_deferred_attributes
|
5
|
+
module TouchLater # :nodoc:
|
6
|
+
def before_committed!
|
7
|
+
touch_deferred_attributes if has_defer_touch_attrs? && persisted?
|
8
|
+
super
|
10
9
|
end
|
11
10
|
|
12
11
|
def touch_later(*names) # :nodoc:
|
13
|
-
unless persisted?
|
14
|
-
raise ActiveRecordError, <<-MSG.squish
|
15
|
-
cannot touch on a new or destroyed record object. Consider using
|
16
|
-
persisted?, new_record?, or destroyed? before touching
|
17
|
-
MSG
|
18
|
-
end
|
12
|
+
_raise_record_not_touched_error unless persisted?
|
19
13
|
|
20
14
|
@_defer_touch_attrs ||= timestamp_attributes_for_update_in_model
|
21
|
-
@_defer_touch_attrs |= names
|
15
|
+
@_defer_touch_attrs |= names.map! do |name|
|
16
|
+
name = name.to_s
|
17
|
+
self.class.attribute_aliases[name] || name
|
18
|
+
end unless names.empty?
|
19
|
+
|
22
20
|
@_touch_time = current_time_from_proper_timezone
|
23
21
|
|
24
22
|
surreptitiously_touch @_defer_touch_attrs
|
25
|
-
|
23
|
+
add_to_transaction
|
24
|
+
@_new_record_before_last_commit ||= false
|
26
25
|
|
27
26
|
# touch the parents as we are not calling the after_save callbacks
|
28
27
|
self.class.reflect_on_all_associations(:belongs_to).each do |r|
|
@@ -35,22 +34,24 @@ module ActiveRecord
|
|
35
34
|
def touch(*names, time: nil) # :nodoc:
|
36
35
|
if has_defer_touch_attrs?
|
37
36
|
names |= @_defer_touch_attrs
|
37
|
+
super(*names, time: time)
|
38
|
+
@_defer_touch_attrs, @_touch_time = nil, nil
|
39
|
+
else
|
40
|
+
super
|
38
41
|
end
|
39
|
-
super(*names, time: time)
|
40
42
|
end
|
41
43
|
|
42
44
|
private
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
def surreptitiously_touch(attr_names)
|
46
|
+
attr_names.each do |attr_name|
|
47
|
+
_write_attribute(attr_name, @_touch_time)
|
48
|
+
clear_attribute_change(attr_name)
|
49
|
+
end
|
47
50
|
end
|
48
51
|
|
49
52
|
def touch_deferred_attributes
|
50
|
-
|
51
|
-
|
52
|
-
@_defer_touch_attrs, @_touch_time = nil, nil
|
53
|
-
end
|
53
|
+
@_skip_dirty_tracking = true
|
54
|
+
touch(time: @_touch_time)
|
54
55
|
end
|
55
56
|
|
56
57
|
def has_defer_touch_attrs?
|
@@ -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
|
@@ -284,8 +271,10 @@ module ActiveRecord
|
|
284
271
|
if options[:on]
|
285
272
|
fire_on = Array(options[:on])
|
286
273
|
assert_valid_transaction_action(fire_on)
|
287
|
-
options[:if] =
|
288
|
-
|
274
|
+
options[:if] = [
|
275
|
+
-> { transaction_include_any_action?(fire_on) },
|
276
|
+
*options[:if]
|
277
|
+
]
|
289
278
|
end
|
290
279
|
end
|
291
280
|
|
@@ -297,41 +286,27 @@ module ActiveRecord
|
|
297
286
|
end
|
298
287
|
|
299
288
|
# See ActiveRecord::Transactions::ClassMethods for detailed documentation.
|
300
|
-
def transaction(options
|
301
|
-
self.class.transaction(options, &block)
|
289
|
+
def transaction(**options, &block)
|
290
|
+
self.class.transaction(**options, &block)
|
302
291
|
end
|
303
292
|
|
304
293
|
def destroy #:nodoc:
|
305
294
|
with_transaction_returning_status { super }
|
306
295
|
end
|
307
296
|
|
308
|
-
def save(
|
309
|
-
rollback_active_record_state! do
|
310
|
-
with_transaction_returning_status { super }
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
def save!(*) #:nodoc:
|
297
|
+
def save(**) #:nodoc:
|
315
298
|
with_transaction_returning_status { super }
|
316
299
|
end
|
317
300
|
|
318
|
-
def
|
301
|
+
def save!(**) #:nodoc:
|
319
302
|
with_transaction_returning_status { super }
|
320
303
|
end
|
321
304
|
|
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
|
305
|
+
def touch(*, **) #:nodoc:
|
306
|
+
with_transaction_returning_status { super }
|
331
307
|
end
|
332
308
|
|
333
309
|
def before_committed! # :nodoc:
|
334
|
-
_run_before_commit_without_transaction_enrollment_callbacks
|
335
310
|
_run_before_commit_callbacks
|
336
311
|
end
|
337
312
|
|
@@ -341,13 +316,12 @@ module ActiveRecord
|
|
341
316
|
# but call it after the commit of a destroyed object.
|
342
317
|
def committed!(should_run_callbacks: true) #:nodoc:
|
343
318
|
force_clear_transaction_record_state
|
344
|
-
if should_run_callbacks
|
319
|
+
if should_run_callbacks
|
345
320
|
@_committed_already_called = true
|
346
|
-
_run_commit_without_transaction_enrollment_callbacks
|
347
321
|
_run_commit_callbacks
|
348
322
|
end
|
349
323
|
ensure
|
350
|
-
@_committed_already_called = false
|
324
|
+
@_committed_already_called = @_trigger_update_callback = @_trigger_destroy_callback = false
|
351
325
|
end
|
352
326
|
|
353
327
|
# Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
|
@@ -355,23 +329,11 @@ module ActiveRecord
|
|
355
329
|
def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
|
356
330
|
if should_run_callbacks
|
357
331
|
_run_rollback_callbacks
|
358
|
-
_run_rollback_without_transaction_enrollment_callbacks
|
359
332
|
end
|
360
333
|
ensure
|
361
334
|
restore_transaction_record_state(force_restore_state)
|
362
335
|
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
|
336
|
+
@_trigger_update_callback = @_trigger_destroy_callback = false if force_restore_state
|
375
337
|
end
|
376
338
|
|
377
339
|
# Executes +method+ within a transaction and captures its return value as a
|
@@ -382,36 +344,40 @@ module ActiveRecord
|
|
382
344
|
# instance.
|
383
345
|
def with_transaction_returning_status
|
384
346
|
status = nil
|
385
|
-
self.class.
|
386
|
-
|
347
|
+
connection = self.class.connection
|
348
|
+
ensure_finalize = !connection.transaction_open?
|
349
|
+
|
350
|
+
connection.transaction do
|
351
|
+
add_to_transaction(ensure_finalize || has_transactional_callbacks?)
|
352
|
+
remember_transaction_record_state
|
353
|
+
|
387
354
|
status = yield
|
388
355
|
raise ActiveRecord::Rollback unless status
|
389
356
|
end
|
390
357
|
status
|
391
|
-
ensure
|
392
|
-
if @transaction_state && @transaction_state.committed?
|
393
|
-
clear_transaction_record_state
|
394
|
-
end
|
395
358
|
end
|
396
359
|
|
397
|
-
|
398
|
-
|
360
|
+
def trigger_transactional_callbacks? # :nodoc:
|
361
|
+
(@_new_record_before_last_commit || _trigger_update_callback) && persisted? ||
|
362
|
+
_trigger_destroy_callback && destroyed?
|
363
|
+
end
|
399
364
|
|
400
365
|
private
|
366
|
+
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
|
401
367
|
|
402
368
|
# Save the new record state and id of a record so it can be restored later if a transaction fails.
|
403
369
|
def remember_transaction_record_state
|
404
|
-
@_start_transaction_state
|
370
|
+
@_start_transaction_state ||= {
|
405
371
|
id: id,
|
406
372
|
new_record: @new_record,
|
373
|
+
previously_new_record: @previously_new_record,
|
407
374
|
destroyed: @destroyed,
|
375
|
+
attributes: @attributes,
|
408
376
|
frozen?: frozen?,
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
end
|
377
|
+
level: 0
|
378
|
+
}
|
379
|
+
@_start_transaction_state[:level] += 1
|
413
380
|
|
414
|
-
def remember_new_record_before_last_commit
|
415
381
|
if _committed_already_called
|
416
382
|
@_new_record_before_last_commit = false
|
417
383
|
else
|
@@ -421,27 +387,32 @@ module ActiveRecord
|
|
421
387
|
|
422
388
|
# Clear the new record state and id of a record.
|
423
389
|
def clear_transaction_record_state
|
424
|
-
|
390
|
+
return unless @_start_transaction_state
|
391
|
+
@_start_transaction_state[:level] -= 1
|
425
392
|
force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
|
426
393
|
end
|
427
394
|
|
428
395
|
# Force to clear the transaction record state.
|
429
396
|
def force_clear_transaction_record_state
|
430
|
-
@_start_transaction_state
|
397
|
+
@_start_transaction_state = nil
|
431
398
|
end
|
432
399
|
|
433
400
|
# 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
|
401
|
+
def restore_transaction_record_state(force_restore_state = false)
|
402
|
+
if restore_state = @_start_transaction_state
|
403
|
+
if force_restore_state || restore_state[:level] <= 1
|
440
404
|
@new_record = restore_state[:new_record]
|
405
|
+
@previously_new_record = restore_state[:previously_new_record]
|
441
406
|
@destroyed = restore_state[:destroyed]
|
442
|
-
|
443
|
-
|
444
|
-
|
407
|
+
@attributes = restore_state[:attributes].map do |attr|
|
408
|
+
value = @attributes.fetch_value(attr.name)
|
409
|
+
attr = attr.with_value_from_user(value) if attr.value != value
|
410
|
+
attr
|
411
|
+
end
|
412
|
+
@mutations_from_database = nil
|
413
|
+
@mutations_before_last_save = nil
|
414
|
+
if @attributes.fetch_value(@primary_key) != restore_state[:id]
|
415
|
+
@attributes.write_from_user(@primary_key, restore_state[:id])
|
445
416
|
end
|
446
417
|
freeze if restore_state[:frozen?]
|
447
418
|
end
|
@@ -462,41 +433,14 @@ module ActiveRecord
|
|
462
433
|
end
|
463
434
|
end
|
464
435
|
|
465
|
-
|
466
|
-
|
436
|
+
# Add the record to the current transaction so that the #after_rollback and #after_commit
|
437
|
+
# callbacks can be called.
|
438
|
+
def add_to_transaction(ensure_finalize = true)
|
439
|
+
self.class.connection.add_transaction_record(self, ensure_finalize)
|
467
440
|
end
|
468
441
|
|
469
442
|
def has_transactional_callbacks?
|
470
443
|
!_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
|
471
444
|
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
445
|
end
|
502
446
|
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
|