activerecord 5.2.8.1 → 6.1.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1347 -624
- 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 +16 -7
- 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 +107 -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 +73 -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 +225 -121
- 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 +341 -99
- 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 +4 -4
- 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 +113 -74
- 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 +478 -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 +94 -10
- 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 +291 -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 +118 -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
@@ -29,9 +29,9 @@ module ActiveRecord
|
|
29
29
|
# == Callbacks
|
30
30
|
#
|
31
31
|
# Association with autosave option defines several callbacks on your
|
32
|
-
# model (before_save, after_create, after_update). Please note that
|
32
|
+
# model (around_save, before_save, after_create, after_update). Please note that
|
33
33
|
# callbacks are executed in the order they were defined in
|
34
|
-
# model. You should avoid modifying the association content
|
34
|
+
# model. You should avoid modifying the association content before
|
35
35
|
# autosave callbacks are executed. Placing your callbacks after
|
36
36
|
# associations is usually a good practice.
|
37
37
|
#
|
@@ -91,8 +91,9 @@ module ActiveRecord
|
|
91
91
|
# post.save # => saves both post and comment
|
92
92
|
#
|
93
93
|
# post = Post.create(title: 'ruby rocks')
|
94
|
-
# post.comments.create(body: 'hello world')
|
95
|
-
#
|
94
|
+
# comment = post.comments.create(body: 'hello world')
|
95
|
+
# comment.body = 'hi everyone'
|
96
|
+
# post.save # => saves post, but not comment
|
96
97
|
#
|
97
98
|
# When <tt>:autosave</tt> is true all children are saved, no matter whether they
|
98
99
|
# are new records or not:
|
@@ -102,11 +103,10 @@ module ActiveRecord
|
|
102
103
|
# end
|
103
104
|
#
|
104
105
|
# post = Post.create(title: 'ruby rocks')
|
105
|
-
# post.comments.create(body: 'hello world')
|
106
|
-
#
|
106
|
+
# comment = post.comments.create(body: 'hello world')
|
107
|
+
# comment.body = 'hi everyone'
|
107
108
|
# post.comments.build(body: "good morning.")
|
108
|
-
# post.
|
109
|
-
# post.save # => saves both post and comments.
|
109
|
+
# post.save # => saves post and both comments.
|
110
110
|
#
|
111
111
|
# Destroying one of the associated models as part of the parent's save action
|
112
112
|
# is as simple as marking it for destruction:
|
@@ -127,6 +127,14 @@ module ActiveRecord
|
|
127
127
|
# Now it _is_ removed from the database:
|
128
128
|
#
|
129
129
|
# Comment.find_by(id: id).nil? # => true
|
130
|
+
#
|
131
|
+
# === Caveats
|
132
|
+
#
|
133
|
+
# Note that autosave will only trigger for already-persisted association records
|
134
|
+
# if the records themselves have been changed. This is to protect against
|
135
|
+
# <tt>SystemStackError</tt> caused by circular association validations. The one
|
136
|
+
# exception is if a custom validation context is used, in which case the validations
|
137
|
+
# will always fire on the associated records.
|
130
138
|
module AutosaveAssociation
|
131
139
|
extend ActiveSupport::Concern
|
132
140
|
|
@@ -147,9 +155,23 @@ module ActiveRecord
|
|
147
155
|
|
148
156
|
module ClassMethods # :nodoc:
|
149
157
|
private
|
158
|
+
if Module.method(:method_defined?).arity == 1 # MRI 2.5 and older
|
159
|
+
using Module.new {
|
160
|
+
refine Module do
|
161
|
+
def method_defined?(method, inherit = true)
|
162
|
+
if inherit
|
163
|
+
super(method)
|
164
|
+
else
|
165
|
+
instance_methods(false).include?(method.to_sym)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
}
|
170
|
+
end
|
150
171
|
|
151
172
|
def define_non_cyclic_method(name, &block)
|
152
|
-
return if method_defined?(name)
|
173
|
+
return if method_defined?(name, false)
|
174
|
+
|
153
175
|
define_method(name) do |*args|
|
154
176
|
result = true; @_already_called ||= {}
|
155
177
|
# Loop prevention for validation of associations
|
@@ -181,8 +203,7 @@ module ActiveRecord
|
|
181
203
|
save_method = :"autosave_associated_records_for_#{reflection.name}"
|
182
204
|
|
183
205
|
if reflection.collection?
|
184
|
-
|
185
|
-
after_save :after_save_collection_association
|
206
|
+
around_save :around_save_collection_association
|
186
207
|
|
187
208
|
define_non_cyclic_method(save_method) { save_collection_association(reflection) }
|
188
209
|
# Doesn't use after_save as that would save associations added in after_create/after_update twice
|
@@ -267,7 +288,6 @@ module ActiveRecord
|
|
267
288
|
end
|
268
289
|
|
269
290
|
private
|
270
|
-
|
271
291
|
# Returns the record for an association collection that should be validated
|
272
292
|
# or saved. If +autosave+ is +false+ only new records will be returned,
|
273
293
|
# unless the parent is/was a new record itself.
|
@@ -281,8 +301,9 @@ module ActiveRecord
|
|
281
301
|
end
|
282
302
|
end
|
283
303
|
|
284
|
-
#
|
285
|
-
# any new ones), and return true if
|
304
|
+
# Go through nested autosave associations that are loaded in memory (without loading
|
305
|
+
# any new ones), and return true if any are changed for autosave.
|
306
|
+
# Returns false if already called to prevent an infinite loop.
|
286
307
|
def nested_records_changed_for_autosave?
|
287
308
|
@_nested_records_changed_for_autosave_already_called ||= false
|
288
309
|
return false if @_nested_records_changed_for_autosave_already_called
|
@@ -330,21 +351,16 @@ module ActiveRecord
|
|
330
351
|
if reflection.options[:autosave]
|
331
352
|
indexed_attribute = !index.nil? && (reflection.options[:index_errors] || ActiveRecord::Base.index_nested_attribute_errors)
|
332
353
|
|
333
|
-
record.errors.each
|
354
|
+
record.errors.group_by_attribute.each { |attribute, errors|
|
334
355
|
attribute = normalize_reflection_attribute(indexed_attribute, reflection, index, attribute)
|
335
|
-
errors[attribute] << message
|
336
|
-
errors[attribute].uniq!
|
337
|
-
end
|
338
356
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
end
|
347
|
-
end
|
357
|
+
errors.each { |error|
|
358
|
+
self.errors.import(
|
359
|
+
error,
|
360
|
+
attribute: attribute
|
361
|
+
)
|
362
|
+
}
|
363
|
+
}
|
348
364
|
else
|
349
365
|
errors.add(reflection.name)
|
350
366
|
end
|
@@ -360,14 +376,15 @@ module ActiveRecord
|
|
360
376
|
end
|
361
377
|
end
|
362
378
|
|
363
|
-
# Is used as
|
379
|
+
# Is used as an around_save callback to check while saving a collection
|
364
380
|
# association whether or not the parent was a new record before saving.
|
365
|
-
def
|
366
|
-
@new_record_before_save
|
367
|
-
|
381
|
+
def around_save_collection_association
|
382
|
+
previously_new_record_before_save = (@new_record_before_save ||= false)
|
383
|
+
@new_record_before_save = !previously_new_record_before_save && new_record?
|
368
384
|
|
369
|
-
|
370
|
-
|
385
|
+
yield
|
386
|
+
ensure
|
387
|
+
@new_record_before_save = previously_new_record_before_save
|
371
388
|
end
|
372
389
|
|
373
390
|
# Saves any new associated records, or all loaded autosave associations if
|
@@ -416,7 +433,7 @@ module ActiveRecord
|
|
416
433
|
saved = record.save(validate: false)
|
417
434
|
end
|
418
435
|
|
419
|
-
raise
|
436
|
+
raise(RecordInvalid.new(association.owner)) unless saved
|
420
437
|
end
|
421
438
|
end
|
422
439
|
end
|
@@ -440,13 +457,13 @@ module ActiveRecord
|
|
440
457
|
if autosave && record.marked_for_destruction?
|
441
458
|
record.destroy
|
442
459
|
elsif autosave != false
|
443
|
-
key = reflection.options[:primary_key] ?
|
460
|
+
key = reflection.options[:primary_key] ? public_send(reflection.options[:primary_key]) : id
|
444
461
|
|
445
|
-
if (autosave && record.changed_for_autosave?) ||
|
462
|
+
if (autosave && record.changed_for_autosave?) || record_changed?(reflection, record, key)
|
446
463
|
unless reflection.through_reflection
|
447
464
|
record[reflection.foreign_key] = key
|
448
465
|
if inverse_reflection = reflection.inverse_of
|
449
|
-
record.association(inverse_reflection.name).
|
466
|
+
record.association(inverse_reflection.name).inversed_from(self)
|
450
467
|
end
|
451
468
|
end
|
452
469
|
|
@@ -468,7 +485,7 @@ module ActiveRecord
|
|
468
485
|
def association_foreign_key_changed?(reflection, record, key)
|
469
486
|
return false if reflection.through_reflection?
|
470
487
|
|
471
|
-
record.
|
488
|
+
record._has_attribute?(reflection.foreign_key) && record._read_attribute(reflection.foreign_key) != key
|
472
489
|
end
|
473
490
|
|
474
491
|
# Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
|
@@ -489,7 +506,7 @@ module ActiveRecord
|
|
489
506
|
saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
|
490
507
|
|
491
508
|
if association.updated?
|
492
|
-
association_id = record.
|
509
|
+
association_id = record.public_send(reflection.options[:primary_key] || :id)
|
493
510
|
self[reflection.foreign_key] = association_id
|
494
511
|
association.loaded!
|
495
512
|
end
|
@@ -504,9 +521,7 @@ module ActiveRecord
|
|
504
521
|
end
|
505
522
|
|
506
523
|
def _ensure_no_duplicate_errors
|
507
|
-
errors.
|
508
|
-
errors[attribute].uniq!
|
509
|
-
end
|
524
|
+
errors.uniq!
|
510
525
|
end
|
511
526
|
end
|
512
527
|
end
|
data/lib/active_record/base.rb
CHANGED
@@ -1,28 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "yaml"
|
4
3
|
require "active_support/benchmarkable"
|
5
4
|
require "active_support/dependencies"
|
6
5
|
require "active_support/descendants_tracker"
|
7
6
|
require "active_support/time"
|
8
|
-
require "active_support/core_ext/module/attribute_accessors"
|
9
|
-
require "active_support/core_ext/array/extract_options"
|
10
|
-
require "active_support/core_ext/hash/deep_merge"
|
11
|
-
require "active_support/core_ext/hash/slice"
|
12
|
-
require "active_support/core_ext/hash/transform_values"
|
13
|
-
require "active_support/core_ext/string/behavior"
|
14
|
-
require "active_support/core_ext/kernel/singleton_class"
|
15
|
-
require "active_support/core_ext/module/introspection"
|
16
|
-
require "active_support/core_ext/object/duplicable"
|
17
7
|
require "active_support/core_ext/class/subclasses"
|
18
|
-
require "active_record/attribute_decorators"
|
19
|
-
require "active_record/define_callbacks"
|
20
|
-
require "active_record/errors"
|
21
8
|
require "active_record/log_subscriber"
|
22
9
|
require "active_record/explain_subscriber"
|
23
10
|
require "active_record/relation/delegation"
|
24
11
|
require "active_record/attributes"
|
25
12
|
require "active_record/type_caster"
|
13
|
+
require "active_record/database_configurations"
|
26
14
|
|
27
15
|
module ActiveRecord #:nodoc:
|
28
16
|
# = Active Record
|
@@ -285,10 +273,11 @@ module ActiveRecord #:nodoc:
|
|
285
273
|
extend Querying
|
286
274
|
extend Translation
|
287
275
|
extend DynamicMatchers
|
276
|
+
extend DelegatedType
|
288
277
|
extend Explain
|
289
278
|
extend Enum
|
290
279
|
extend Delegation::DelegateCache
|
291
|
-
extend
|
280
|
+
extend Aggregations::ClassMethods
|
292
281
|
|
293
282
|
include Core
|
294
283
|
include Persistence
|
@@ -303,10 +292,8 @@ module ActiveRecord #:nodoc:
|
|
303
292
|
include Validations
|
304
293
|
include CounterCache
|
305
294
|
include Attributes
|
306
|
-
include AttributeDecorators
|
307
295
|
include Locking::Optimistic
|
308
296
|
include Locking::Pessimistic
|
309
|
-
include DefineCallbacks
|
310
297
|
include AttributeMethods
|
311
298
|
include Callbacks
|
312
299
|
include Timestamp
|
@@ -314,7 +301,6 @@ module ActiveRecord #:nodoc:
|
|
314
301
|
include ActiveModel::SecurePassword
|
315
302
|
include AutosaveAssociation
|
316
303
|
include NestedAttributes
|
317
|
-
include Aggregations
|
318
304
|
include Transactions
|
319
305
|
include TouchLater
|
320
306
|
include NoTouching
|
@@ -322,6 +308,7 @@ module ActiveRecord #:nodoc:
|
|
322
308
|
include Serialization
|
323
309
|
include Store
|
324
310
|
include SecureToken
|
311
|
+
include SignedId
|
325
312
|
include Suppressor
|
326
313
|
end
|
327
314
|
|
@@ -4,7 +4,7 @@ module ActiveRecord
|
|
4
4
|
# = Active Record \Callbacks
|
5
5
|
#
|
6
6
|
# \Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
|
7
|
-
# before or after
|
7
|
+
# before or after a change in the object state. This can be used to make sure that associated and
|
8
8
|
# dependent objects are deleted when {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] is called (by overwriting +before_destroy+) or
|
9
9
|
# to massage attributes before they're validated (by overwriting +before_validation+).
|
10
10
|
# As an example of the callbacks initiated, consider the {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] call for a new record:
|
@@ -32,7 +32,7 @@ module ActiveRecord
|
|
32
32
|
# is found and instantiated by a finder, with <tt>after_initialize</tt> being triggered after new objects
|
33
33
|
# are instantiated as well.
|
34
34
|
#
|
35
|
-
# There are nineteen callbacks in total, which give
|
35
|
+
# There are nineteen callbacks in total, which give a lot of control over how to react and prepare for each state in the
|
36
36
|
# Active Record life cycle. The sequence for calling {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] for an existing record is similar,
|
37
37
|
# except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback.
|
38
38
|
#
|
@@ -64,7 +64,7 @@ module ActiveRecord
|
|
64
64
|
#
|
65
65
|
# Besides the overwritable callback methods, it's also possible to register callbacks through the
|
66
66
|
# use of the callback macros. Their main advantage is that the macros add behavior into a callback
|
67
|
-
# queue that is kept intact
|
67
|
+
# queue that is kept intact through an inheritance hierarchy.
|
68
68
|
#
|
69
69
|
# class Topic < ActiveRecord::Base
|
70
70
|
# before_destroy :destroy_author
|
@@ -74,22 +74,8 @@ module ActiveRecord
|
|
74
74
|
# before_destroy :destroy_readers
|
75
75
|
# end
|
76
76
|
#
|
77
|
-
#
|
78
|
-
# run, both +destroy_author+ and +destroy_readers+ are called.
|
79
|
-
# where the +before_destroy+ method is overridden:
|
80
|
-
#
|
81
|
-
# class Topic < ActiveRecord::Base
|
82
|
-
# def before_destroy() destroy_author end
|
83
|
-
# end
|
84
|
-
#
|
85
|
-
# class Reply < Topic
|
86
|
-
# def before_destroy() destroy_readers end
|
87
|
-
# end
|
88
|
-
#
|
89
|
-
# In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
|
90
|
-
# So, use the callback macros when you want to ensure that a certain callback is called for the entire
|
91
|
-
# hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant
|
92
|
-
# to decide whether they want to call +super+ and trigger the inherited callbacks.
|
77
|
+
# When <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
|
78
|
+
# run, both +destroy_author+ and +destroy_readers+ are called.
|
93
79
|
#
|
94
80
|
# *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
|
95
81
|
# callbacks before specifying the associations. Otherwise, you might trigger the loading of a
|
@@ -97,10 +83,9 @@ module ActiveRecord
|
|
97
83
|
#
|
98
84
|
# == Types of callbacks
|
99
85
|
#
|
100
|
-
# There are
|
101
|
-
# inline methods (using a proc). Method references and callback objects
|
102
|
-
#
|
103
|
-
# creating mix-ins).
|
86
|
+
# There are three types of callbacks accepted by the callback macros: method references (symbol), callback objects,
|
87
|
+
# inline methods (using a proc). Method references and callback objects are the recommended approaches,
|
88
|
+
# inline methods using a proc are sometimes appropriate (such as for creating mix-ins).
|
104
89
|
#
|
105
90
|
# The method reference callbacks work by specifying a protected or private method available in the object, like this:
|
106
91
|
#
|
@@ -109,7 +94,7 @@ module ActiveRecord
|
|
109
94
|
#
|
110
95
|
# private
|
111
96
|
# def delete_parents
|
112
|
-
# self.class.
|
97
|
+
# self.class.delete_by(parent_id: id)
|
113
98
|
# end
|
114
99
|
# end
|
115
100
|
#
|
@@ -142,7 +127,7 @@ module ActiveRecord
|
|
142
127
|
# end
|
143
128
|
# end
|
144
129
|
#
|
145
|
-
# So you specify the object you want messaged on a given callback. When that callback is triggered, the object has
|
130
|
+
# So you specify the object you want to be messaged on a given callback. When that callback is triggered, the object has
|
146
131
|
# a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other
|
147
132
|
# initialization data such as the name of the attribute to work with:
|
148
133
|
#
|
@@ -193,8 +178,8 @@ module ActiveRecord
|
|
193
178
|
#
|
194
179
|
# == Ordering callbacks
|
195
180
|
#
|
196
|
-
# Sometimes
|
197
|
-
# callback (+log_children+ in this case) should be executed before the children
|
181
|
+
# Sometimes application code requires that callbacks execute in a specific order. For example, a +before_destroy+
|
182
|
+
# callback (+log_children+ in this case) should be executed before records in the +children+ association are destroyed by the
|
198
183
|
# <tt>dependent: :destroy</tt> option.
|
199
184
|
#
|
200
185
|
# Let's look at the code below:
|
@@ -210,8 +195,8 @@ module ActiveRecord
|
|
210
195
|
# end
|
211
196
|
# end
|
212
197
|
#
|
213
|
-
# In this case, the problem is that when the +before_destroy+ callback is executed, the children
|
214
|
-
# because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback
|
198
|
+
# In this case, the problem is that when the +before_destroy+ callback is executed, records in the +children+ association no
|
199
|
+
# longer exist because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback was executed first.
|
215
200
|
# You can use the +prepend+ option on the +before_destroy+ callback to avoid this.
|
216
201
|
#
|
217
202
|
# class Topic < ActiveRecord::Base
|
@@ -225,7 +210,7 @@ module ActiveRecord
|
|
225
210
|
# end
|
226
211
|
# end
|
227
212
|
#
|
228
|
-
# This way, the +before_destroy+
|
213
|
+
# This way, the +before_destroy+ is executed before the <tt>dependent: :destroy</tt> is called, and the data is still available.
|
229
214
|
#
|
230
215
|
# Also, there are cases when you want several callbacks of the same type to
|
231
216
|
# be executed in order.
|
@@ -249,10 +234,10 @@ module ActiveRecord
|
|
249
234
|
# end
|
250
235
|
# end
|
251
236
|
#
|
252
|
-
# In this case the +log_children+
|
237
|
+
# In this case the +log_children+ is executed before +do_something_else+.
|
253
238
|
# The same applies to all non-transactional callbacks.
|
254
239
|
#
|
255
|
-
#
|
240
|
+
# As seen below, in case there are multiple transactional callbacks the order
|
256
241
|
# is reversed.
|
257
242
|
#
|
258
243
|
# For example:
|
@@ -274,16 +259,16 @@ module ActiveRecord
|
|
274
259
|
# end
|
275
260
|
# end
|
276
261
|
#
|
277
|
-
# In this case the +do_something_else+
|
262
|
+
# In this case the +do_something_else+ is executed before +log_children+.
|
278
263
|
#
|
279
264
|
# == \Transactions
|
280
265
|
#
|
281
266
|
# The entire callback chain of a {#save}[rdoc-ref:Persistence#save], {#save!}[rdoc-ref:Persistence#save!],
|
282
267
|
# or {#destroy}[rdoc-ref:Persistence#destroy] call runs within a transaction. That includes <tt>after_*</tt> hooks.
|
283
|
-
# If everything goes fine a COMMIT is executed once the chain has been completed.
|
268
|
+
# If everything goes fine a +COMMIT+ is executed once the chain has been completed.
|
284
269
|
#
|
285
|
-
# If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued. You
|
286
|
-
# can also trigger a ROLLBACK raising an exception in any of the callbacks,
|
270
|
+
# If a <tt>before_*</tt> callback cancels the action a +ROLLBACK+ is issued. You
|
271
|
+
# can also trigger a +ROLLBACK+ raising an exception in any of the callbacks,
|
287
272
|
# including <tt>after_*</tt> hooks. Note, however, that in that case the client
|
288
273
|
# needs to be aware of it because an ordinary {#save}[rdoc-ref:Persistence#save] will raise such exception
|
289
274
|
# instead of quietly returning +false+.
|
@@ -294,17 +279,17 @@ module ActiveRecord
|
|
294
279
|
# <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
|
295
280
|
# defines what part of the chain the callback runs in.
|
296
281
|
#
|
297
|
-
# To find all callbacks in the before_save callback chain:
|
282
|
+
# To find all callbacks in the +before_save+ callback chain:
|
298
283
|
#
|
299
284
|
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
|
300
285
|
#
|
301
|
-
# Returns an array of callback objects that form the before_save chain.
|
286
|
+
# Returns an array of callback objects that form the +before_save+ chain.
|
302
287
|
#
|
303
288
|
# To further check if the before_save chain contains a proc defined as <tt>rest_when_dead</tt> use the <tt>filter</tt> property of the callback object:
|
304
289
|
#
|
305
290
|
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
|
306
291
|
#
|
307
|
-
# Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.
|
292
|
+
# Returns true or false depending on whether the proc is contained in the +before_save+ callback chain on a Topic model.
|
308
293
|
#
|
309
294
|
module Callbacks
|
310
295
|
extend ActiveSupport::Concern
|
@@ -316,6 +301,137 @@ module ActiveRecord
|
|
316
301
|
:before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
|
317
302
|
]
|
318
303
|
|
304
|
+
module ClassMethods
|
305
|
+
include ActiveModel::Callbacks
|
306
|
+
|
307
|
+
##
|
308
|
+
# :method: after_initialize
|
309
|
+
#
|
310
|
+
# :call-seq: after_initialize(*args, &block)
|
311
|
+
#
|
312
|
+
# Registers a callback to be called after a record is instantiated. See
|
313
|
+
# ActiveRecord::Callbacks for more information.
|
314
|
+
|
315
|
+
##
|
316
|
+
# :method: after_find
|
317
|
+
#
|
318
|
+
# :call-seq: after_find(*args, &block)
|
319
|
+
#
|
320
|
+
# Registers a callback to be called after a record is instantiated
|
321
|
+
# via a finder. See ActiveRecord::Callbacks for more information.
|
322
|
+
|
323
|
+
##
|
324
|
+
# :method: after_touch
|
325
|
+
#
|
326
|
+
# :call-seq: after_touch(*args, &block)
|
327
|
+
#
|
328
|
+
# Registers a callback to be called after a record is touched. See
|
329
|
+
# ActiveRecord::Callbacks for more information.
|
330
|
+
|
331
|
+
##
|
332
|
+
# :method: before_save
|
333
|
+
#
|
334
|
+
# :call-seq: before_save(*args, &block)
|
335
|
+
#
|
336
|
+
# Registers a callback to be called before a record is saved. See
|
337
|
+
# ActiveRecord::Callbacks for more information.
|
338
|
+
|
339
|
+
##
|
340
|
+
# :method: around_save
|
341
|
+
#
|
342
|
+
# :call-seq: around_save(*args, &block)
|
343
|
+
#
|
344
|
+
# Registers a callback to be called around the save of a record. See
|
345
|
+
# ActiveRecord::Callbacks for more information.
|
346
|
+
|
347
|
+
##
|
348
|
+
# :method: after_save
|
349
|
+
#
|
350
|
+
# :call-seq: after_save(*args, &block)
|
351
|
+
#
|
352
|
+
# Registers a callback to be called after a record is saved. See
|
353
|
+
# ActiveRecord::Callbacks for more information.
|
354
|
+
|
355
|
+
##
|
356
|
+
# :method: before_create
|
357
|
+
#
|
358
|
+
# :call-seq: before_create(*args, &block)
|
359
|
+
#
|
360
|
+
# Registers a callback to be called before a record is created. See
|
361
|
+
# ActiveRecord::Callbacks for more information.
|
362
|
+
|
363
|
+
##
|
364
|
+
# :method: around_create
|
365
|
+
#
|
366
|
+
# :call-seq: around_create(*args, &block)
|
367
|
+
#
|
368
|
+
# Registers a callback to be called around the creation of a record. See
|
369
|
+
# ActiveRecord::Callbacks for more information.
|
370
|
+
|
371
|
+
##
|
372
|
+
# :method: after_create
|
373
|
+
#
|
374
|
+
# :call-seq: after_create(*args, &block)
|
375
|
+
#
|
376
|
+
# Registers a callback to be called after a record is created. See
|
377
|
+
# ActiveRecord::Callbacks for more information.
|
378
|
+
|
379
|
+
##
|
380
|
+
# :method: before_update
|
381
|
+
#
|
382
|
+
# :call-seq: before_update(*args, &block)
|
383
|
+
#
|
384
|
+
# Registers a callback to be called before a record is updated. See
|
385
|
+
# ActiveRecord::Callbacks for more information.
|
386
|
+
|
387
|
+
##
|
388
|
+
# :method: around_update
|
389
|
+
#
|
390
|
+
# :call-seq: around_update(*args, &block)
|
391
|
+
#
|
392
|
+
# Registers a callback to be called around the update of a record. See
|
393
|
+
# ActiveRecord::Callbacks for more information.
|
394
|
+
|
395
|
+
##
|
396
|
+
# :method: after_update
|
397
|
+
#
|
398
|
+
# :call-seq: after_update(*args, &block)
|
399
|
+
#
|
400
|
+
# Registers a callback to be called after a record is updated. See
|
401
|
+
# ActiveRecord::Callbacks for more information.
|
402
|
+
|
403
|
+
##
|
404
|
+
# :method: before_destroy
|
405
|
+
#
|
406
|
+
# :call-seq: before_destroy(*args, &block)
|
407
|
+
#
|
408
|
+
# Registers a callback to be called before a record is destroyed. See
|
409
|
+
# ActiveRecord::Callbacks for more information.
|
410
|
+
|
411
|
+
##
|
412
|
+
# :method: around_destroy
|
413
|
+
#
|
414
|
+
# :call-seq: around_destroy(*args, &block)
|
415
|
+
#
|
416
|
+
# Registers a callback to be called around the destruction of a record.
|
417
|
+
# See ActiveRecord::Callbacks for more information.
|
418
|
+
|
419
|
+
##
|
420
|
+
# :method: after_destroy
|
421
|
+
#
|
422
|
+
# :call-seq: after_destroy(*args, &block)
|
423
|
+
#
|
424
|
+
# Registers a callback to be called after a record is destroyed. See
|
425
|
+
# ActiveRecord::Callbacks for more information.
|
426
|
+
end
|
427
|
+
|
428
|
+
included do
|
429
|
+
include ActiveModel::Validations::Callbacks
|
430
|
+
|
431
|
+
define_model_callbacks :initialize, :find, :touch, only: :after
|
432
|
+
define_model_callbacks :save, :create, :update, :destroy
|
433
|
+
end
|
434
|
+
|
319
435
|
def destroy #:nodoc:
|
320
436
|
@_destroy_callback_already_called ||= false
|
321
437
|
return if @_destroy_callback_already_called
|
@@ -328,7 +444,7 @@ module ActiveRecord
|
|
328
444
|
@_destroy_callback_already_called = false
|
329
445
|
end
|
330
446
|
|
331
|
-
def touch(
|
447
|
+
def touch(*, **) #:nodoc:
|
332
448
|
_run_touch_callbacks { super }
|
333
449
|
end
|
334
450
|
|
@@ -337,8 +453,7 @@ module ActiveRecord
|
|
337
453
|
end
|
338
454
|
|
339
455
|
private
|
340
|
-
|
341
|
-
def create_or_update(*)
|
456
|
+
def create_or_update(**)
|
342
457
|
_run_save_callbacks { super }
|
343
458
|
end
|
344
459
|
|
@@ -346,7 +461,7 @@ module ActiveRecord
|
|
346
461
|
_run_create_callbacks { super }
|
347
462
|
end
|
348
463
|
|
349
|
-
def _update_record
|
464
|
+
def _update_record
|
350
465
|
_run_update_callbacks { super }
|
351
466
|
end
|
352
467
|
end
|
@@ -22,7 +22,7 @@ module ActiveRecord
|
|
22
22
|
|
23
23
|
def load(yaml)
|
24
24
|
return object_class.new if object_class != Object && yaml.nil?
|
25
|
-
return yaml unless yaml.is_a?(String) &&
|
25
|
+
return yaml unless yaml.is_a?(String) && yaml.start_with?("---")
|
26
26
|
obj = yaml_load(yaml)
|
27
27
|
|
28
28
|
assert_valid_value(obj, action: "load")
|
@@ -39,21 +39,30 @@ module ActiveRecord
|
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
42
|
-
|
43
42
|
def check_arity_of_constructor
|
44
43
|
load(nil)
|
45
44
|
rescue ArgumentError
|
46
45
|
raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
|
47
46
|
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
else
|
53
|
-
if YAML.respond_to?(:unsafe_load)
|
48
|
+
if YAML.respond_to?(:unsafe_load)
|
49
|
+
def yaml_load(payload)
|
50
|
+
if ActiveRecord::Base.use_yaml_unsafe_load
|
54
51
|
YAML.unsafe_load(payload)
|
52
|
+
elsif YAML.method(:safe_load).parameters.include?([:key, :permitted_classes])
|
53
|
+
YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
|
55
54
|
else
|
55
|
+
YAML.safe_load(payload, ActiveRecord::Base.yaml_column_permitted_classes, [], true)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
def yaml_load(payload)
|
60
|
+
if ActiveRecord::Base.use_yaml_unsafe_load
|
56
61
|
YAML.load(payload)
|
62
|
+
elsif YAML.method(:safe_load).parameters.include?([:key, :permitted_classes])
|
63
|
+
YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
|
64
|
+
else
|
65
|
+
YAML.safe_load(payload, ActiveRecord::Base.yaml_column_permitted_classes, [], true)
|
57
66
|
end
|
58
67
|
end
|
59
68
|
end
|