activerecord 6.1.7 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +520 -1385
- data/MIT-LICENSE +1 -1
- data/README.rdoc +31 -31
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +17 -14
- data/lib/active_record/association_relation.rb +2 -12
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +60 -21
- data/lib/active_record/associations/association_scope.rb +17 -12
- data/lib/active_record/associations/belongs_to_association.rb +37 -11
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -4
- data/lib/active_record/associations/builder/association.rb +11 -5
- data/lib/active_record/associations/builder/belongs_to.rb +41 -14
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
- data/lib/active_record/associations/builder/has_many.rb +4 -4
- data/lib/active_record/associations/builder/has_one.rb +4 -4
- data/lib/active_record/associations/builder/singular_association.rb +6 -2
- data/lib/active_record/associations/collection_association.rb +46 -36
- data/lib/active_record/associations/collection_proxy.rb +44 -16
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +29 -19
- data/lib/active_record/associations/has_many_through_association.rb +12 -7
- data/lib/active_record/associations/has_one_association.rb +20 -10
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +27 -25
- data/lib/active_record/associations/join_dependency.rb +23 -15
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +212 -53
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +153 -0
- data/lib/active_record/associations/preloader/through_association.rb +50 -16
- data/lib/active_record/associations/preloader.rb +50 -121
- data/lib/active_record/associations/singular_association.rb +15 -3
- data/lib/active_record/associations/through_association.rb +25 -14
- data/lib/active_record/associations.rb +404 -509
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +2 -14
- data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +73 -22
- data/lib/active_record/attribute_methods/primary_key.rb +47 -27
- data/lib/active_record/attribute_methods/query.rb +31 -19
- data/lib/active_record/attribute_methods/read.rb +14 -11
- data/lib/active_record/attribute_methods/serialization.rb +174 -37
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -9
- data/lib/active_record/attribute_methods/write.rb +12 -15
- data/lib/active_record/attribute_methods.rb +164 -52
- data/lib/active_record/attributes.rb +51 -49
- data/lib/active_record/autosave_association.rb +74 -57
- data/lib/active_record/base.rb +27 -5
- data/lib/active_record/callbacks.rb +18 -34
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -46
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +327 -612
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -60
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +201 -64
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -131
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +377 -142
- data/lib/active_record/connection_adapters/abstract/transaction.rb +361 -76
- data/lib/active_record/connection_adapters/abstract_adapter.rb +624 -163
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +345 -166
- data/lib/active_record/connection_adapters/column.rb +13 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -130
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -55
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +45 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +107 -68
- data/lib/active_record/connection_adapters/pool_config.rb +26 -16
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +114 -54
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +137 -104
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +173 -3
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +401 -77
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +518 -251
- data/lib/active_record/connection_adapters/schema_cache.rb +326 -102
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +78 -55
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +68 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +66 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +372 -130
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
- data/lib/active_record/connection_adapters.rb +130 -6
- data/lib/active_record/connection_handling.rb +132 -146
- data/lib/active_record/core.rb +276 -251
- data/lib/active_record/counter_cache.rb +68 -34
- data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -3
- data/lib/active_record/database_configurations/database_config.rb +34 -10
- data/lib/active_record/database_configurations/hash_config.rb +107 -31
- data/lib/active_record/database_configurations/url_config.rb +38 -13
- data/lib/active_record/database_configurations.rb +96 -60
- data/lib/active_record/delegated_type.rb +90 -20
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +4 -2
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +3 -3
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +230 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +170 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +96 -0
- data/lib/active_record/encryption/null_encryptor.rb +25 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
- data/lib/active_record/encryption/scheme.rb +100 -0
- data/lib/active_record/encryption.rb +56 -0
- data/lib/active_record/enum.rb +163 -63
- data/lib/active_record/errors.rb +210 -27
- data/lib/active_record/explain.rb +21 -12
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +70 -14
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +179 -112
- data/lib/active_record/future_result.rb +178 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +85 -31
- data/lib/active_record/insert_all.rb +148 -32
- data/lib/active_record/integration.rb +14 -10
- data/lib/active_record/internal_metadata.rb +123 -23
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +43 -27
- data/lib/active_record/locking/pessimistic.rb +15 -6
- data/lib/active_record/log_subscriber.rb +41 -29
- data/lib/active_record/marshalling.rb +56 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
- data/lib/active_record/middleware/database_selector.rb +23 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +113 -16
- data/lib/active_record/migration/compatibility.rb +235 -46
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +374 -177
- data/lib/active_record/model_schema.rb +143 -159
- data/lib/active_record/nested_attributes.rb +48 -21
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +282 -283
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +19 -25
- data/lib/active_record/query_logs.rb +189 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +44 -9
- data/lib/active_record/railtie.rb +234 -71
- data/lib/active_record/railties/controller_runtime.rb +25 -11
- data/lib/active_record/railties/databases.rake +189 -256
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +41 -3
- data/lib/active_record/reflection.rb +325 -103
- data/lib/active_record/relation/batches/batch_enumerator.rb +38 -9
- data/lib/active_record/relation/batches.rb +198 -63
- data/lib/active_record/relation/calculations.rb +300 -111
- data/lib/active_record/relation/delegation.rb +33 -22
- data/lib/active_record/relation/finder_methods.rb +123 -52
- data/lib/active_record/relation/merger.rb +26 -19
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +38 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +29 -22
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +842 -150
- data/lib/active_record/relation/record_fetch_warning.rb +10 -9
- data/lib/active_record/relation/spawn_methods.rb +7 -6
- data/lib/active_record/relation/where_clause.rb +15 -36
- data/lib/active_record/relation.rb +736 -145
- data/lib/active_record/result.rb +67 -54
- data/lib/active_record/runtime_registry.rb +71 -13
- data/lib/active_record/sanitization.rb +84 -34
- data/lib/active_record/schema.rb +39 -23
- data/lib/active_record/schema_dumper.rb +90 -31
- data/lib/active_record/schema_migration.rb +74 -23
- data/lib/active_record/scoping/default.rb +72 -15
- data/lib/active_record/scoping/named.rb +5 -13
- data/lib/active_record/scoping.rb +65 -34
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +30 -9
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/store.rb +10 -10
- data/lib/active_record/suppressor.rb +13 -15
- data/lib/active_record/table_metadata.rb +7 -3
- data/lib/active_record/tasks/database_tasks.rb +277 -149
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
- data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +173 -155
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +32 -19
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +12 -7
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +118 -41
- data/lib/active_record/translation.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +32 -14
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +9 -7
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +13 -7
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +64 -15
- data/lib/active_record/validations.rb +12 -5
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +444 -32
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/binary.rb +6 -7
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
- data/lib/arel/nodes/node.rb +115 -5
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +13 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +7 -2
- data/lib/arel/predications.rb +14 -4
- data/lib/arel/select_manager.rb +11 -5
- data/lib/arel/table.rb +9 -6
- data/lib/arel/tree_manager.rb +8 -15
- data/lib/arel/update_manager.rb +20 -5
- data/lib/arel/visitors/dot.rb +81 -90
- data/lib/arel/visitors/mysql.rb +23 -5
- data/lib/arel/visitors/postgresql.rb +1 -22
- data/lib/arel/visitors/to_sql.rb +170 -36
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +23 -4
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +100 -14
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -67
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_record/associations/nested_error"
|
4
|
+
|
3
5
|
module ActiveRecord
|
4
6
|
# = Active Record Autosave Association
|
5
7
|
#
|
@@ -26,7 +28,7 @@ module ActiveRecord
|
|
26
28
|
#
|
27
29
|
# Child records are validated unless <tt>:validate</tt> is +false+.
|
28
30
|
#
|
29
|
-
# == Callbacks
|
31
|
+
# == \Callbacks
|
30
32
|
#
|
31
33
|
# Association with autosave option defines several callbacks on your
|
32
34
|
# model (around_save, before_save, after_create, after_update). Please note that
|
@@ -138,7 +140,7 @@ module ActiveRecord
|
|
138
140
|
module AutosaveAssociation
|
139
141
|
extend ActiveSupport::Concern
|
140
142
|
|
141
|
-
module AssociationBuilderExtension
|
143
|
+
module AssociationBuilderExtension # :nodoc:
|
142
144
|
def self.build(model, reflection)
|
143
145
|
model.send(:add_autosave_association_callbacks, reflection)
|
144
146
|
end
|
@@ -150,25 +152,10 @@ module ActiveRecord
|
|
150
152
|
|
151
153
|
included do
|
152
154
|
Associations::Builder::Association.extensions << AssociationBuilderExtension
|
153
|
-
mattr_accessor :index_nested_attribute_errors, instance_writer: false, default: false
|
154
155
|
end
|
155
156
|
|
156
157
|
module ClassMethods # :nodoc:
|
157
158
|
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
|
171
|
-
|
172
159
|
def define_non_cyclic_method(name, &block)
|
173
160
|
return if method_defined?(name, false)
|
174
161
|
|
@@ -210,7 +197,7 @@ module ActiveRecord
|
|
210
197
|
after_create save_method
|
211
198
|
after_update save_method
|
212
199
|
elsif reflection.has_one?
|
213
|
-
|
200
|
+
define_non_cyclic_method(save_method) { save_has_one_association(reflection) }
|
214
201
|
# Configures two callbacks instead of a single after_save so that
|
215
202
|
# the model may rely on their execution order relative to its
|
216
203
|
# own callbacks.
|
@@ -288,6 +275,11 @@ module ActiveRecord
|
|
288
275
|
end
|
289
276
|
|
290
277
|
private
|
278
|
+
def init_internals
|
279
|
+
super
|
280
|
+
@_already_called = nil
|
281
|
+
end
|
282
|
+
|
291
283
|
# Returns the record for an association collection that should be validated
|
292
284
|
# or saved. If +autosave+ is +false+ only new records will be returned,
|
293
285
|
# unless the parent is/was a new record itself.
|
@@ -325,7 +317,7 @@ module ActiveRecord
|
|
325
317
|
def validate_single_association(reflection)
|
326
318
|
association = association_instance_get(reflection.name)
|
327
319
|
record = association && association.reader
|
328
|
-
association_valid?(
|
320
|
+
association_valid?(association, record) if record && (record.changed_for_autosave? || custom_validation_context?)
|
329
321
|
end
|
330
322
|
|
331
323
|
# Validate the associated records if <tt>:validate</tt> or
|
@@ -334,7 +326,7 @@ module ActiveRecord
|
|
334
326
|
def validate_collection_association(reflection)
|
335
327
|
if association = association_instance_get(reflection.name)
|
336
328
|
if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave])
|
337
|
-
records.
|
329
|
+
records.each { |record| association_valid?(association, record) }
|
338
330
|
end
|
339
331
|
end
|
340
332
|
end
|
@@ -342,40 +334,25 @@ module ActiveRecord
|
|
342
334
|
# Returns whether or not the association is valid and applies any errors to
|
343
335
|
# the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
|
344
336
|
# enabled records if they're marked_for_destruction? or destroyed.
|
345
|
-
def association_valid?(
|
346
|
-
return true if record.destroyed? || (
|
337
|
+
def association_valid?(association, record)
|
338
|
+
return true if record.destroyed? || (association.options[:autosave] && record.marked_for_destruction?)
|
347
339
|
|
348
340
|
context = validation_context if custom_validation_context?
|
349
341
|
|
350
342
|
unless valid = record.valid?(context)
|
351
|
-
if
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
errors.each { |error|
|
358
|
-
self.errors.import(
|
359
|
-
error,
|
360
|
-
attribute: attribute
|
361
|
-
)
|
362
|
-
}
|
343
|
+
if association.options[:autosave]
|
344
|
+
record.errors.each { |error|
|
345
|
+
self.errors.objects.append(
|
346
|
+
Associations::NestedError.new(association, error)
|
347
|
+
)
|
363
348
|
}
|
364
349
|
else
|
365
|
-
errors.add(reflection.name)
|
350
|
+
errors.add(association.reflection.name)
|
366
351
|
end
|
367
352
|
end
|
368
353
|
valid
|
369
354
|
end
|
370
355
|
|
371
|
-
def normalize_reflection_attribute(indexed_attribute, reflection, index, attribute)
|
372
|
-
if indexed_attribute
|
373
|
-
"#{reflection.name}[#{index}].#{attribute}"
|
374
|
-
else
|
375
|
-
"#{reflection.name}.#{attribute}"
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
356
|
# Is used as an around_save callback to check while saving a collection
|
380
357
|
# association whether or not the parent was a new record before saving.
|
381
358
|
def around_save_collection_association
|
@@ -419,6 +396,8 @@ module ActiveRecord
|
|
419
396
|
saved = true
|
420
397
|
|
421
398
|
if autosave != false && (new_record_before_save || record.new_record?)
|
399
|
+
association.set_inverse_instance(record)
|
400
|
+
|
422
401
|
if autosave
|
423
402
|
saved = association.insert_record(record, false)
|
424
403
|
elsif !reflection.nested?
|
@@ -449,7 +428,9 @@ module ActiveRecord
|
|
449
428
|
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
|
450
429
|
def save_has_one_association(reflection)
|
451
430
|
association = association_instance_get(reflection.name)
|
452
|
-
|
431
|
+
return unless association && association.loaded?
|
432
|
+
|
433
|
+
record = association.load_target
|
453
434
|
|
454
435
|
if record && !record.destroyed?
|
455
436
|
autosave = reflection.options[:autosave]
|
@@ -457,14 +438,19 @@ module ActiveRecord
|
|
457
438
|
if autosave && record.marked_for_destruction?
|
458
439
|
record.destroy
|
459
440
|
elsif autosave != false
|
460
|
-
|
441
|
+
primary_key = Array(compute_primary_key(reflection, self)).map(&:to_s)
|
442
|
+
primary_key_value = primary_key.map { |key| _read_attribute(key) }
|
461
443
|
|
462
|
-
if (autosave && record.changed_for_autosave?) ||
|
444
|
+
if (autosave && record.changed_for_autosave?) || _record_changed?(reflection, record, primary_key_value)
|
463
445
|
unless reflection.through_reflection
|
464
|
-
|
465
|
-
|
466
|
-
|
446
|
+
foreign_key = Array(reflection.foreign_key)
|
447
|
+
primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
|
448
|
+
|
449
|
+
primary_key_foreign_key_pairs.each do |primary_key, foreign_key|
|
450
|
+
association_id = _read_attribute(primary_key)
|
451
|
+
record[foreign_key] = association_id unless record[foreign_key] == association_id
|
467
452
|
end
|
453
|
+
association.set_inverse_instance(record)
|
468
454
|
end
|
469
455
|
|
470
456
|
saved = record.save(validate: !autosave)
|
@@ -476,16 +462,28 @@ module ActiveRecord
|
|
476
462
|
end
|
477
463
|
|
478
464
|
# If the record is new or it has changed, returns true.
|
479
|
-
def
|
465
|
+
def _record_changed?(reflection, record, key)
|
480
466
|
record.new_record? ||
|
481
|
-
association_foreign_key_changed?(reflection, record, key) ||
|
467
|
+
(association_foreign_key_changed?(reflection, record, key) ||
|
468
|
+
inverse_polymorphic_association_changed?(reflection, record)) ||
|
482
469
|
record.will_save_change_to_attribute?(reflection.foreign_key)
|
483
470
|
end
|
484
471
|
|
485
472
|
def association_foreign_key_changed?(reflection, record, key)
|
486
473
|
return false if reflection.through_reflection?
|
487
474
|
|
488
|
-
|
475
|
+
foreign_key = Array(reflection.foreign_key)
|
476
|
+
return false unless foreign_key.all? { |key| record._has_attribute?(key) }
|
477
|
+
|
478
|
+
foreign_key.map { |key| record._read_attribute(key) } != Array(key)
|
479
|
+
end
|
480
|
+
|
481
|
+
def inverse_polymorphic_association_changed?(reflection, record)
|
482
|
+
return false unless reflection.inverse_of&.polymorphic?
|
483
|
+
|
484
|
+
class_name = record._read_attribute(reflection.inverse_of.foreign_type)
|
485
|
+
|
486
|
+
reflection.active_record != record.class.polymorphic_class_for(class_name)
|
489
487
|
end
|
490
488
|
|
491
489
|
# Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
|
@@ -500,14 +498,21 @@ module ActiveRecord
|
|
500
498
|
autosave = reflection.options[:autosave]
|
501
499
|
|
502
500
|
if autosave && record.marked_for_destruction?
|
503
|
-
|
501
|
+
foreign_key = Array(reflection.foreign_key)
|
502
|
+
foreign_key.each { |key| self[key] = nil }
|
504
503
|
record.destroy
|
505
504
|
elsif autosave != false
|
506
505
|
saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
|
507
506
|
|
508
507
|
if association.updated?
|
509
|
-
|
510
|
-
|
508
|
+
primary_key = Array(compute_primary_key(reflection, record)).map(&:to_s)
|
509
|
+
foreign_key = Array(reflection.foreign_key)
|
510
|
+
|
511
|
+
primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
|
512
|
+
primary_key_foreign_key_pairs.each do |primary_key, foreign_key|
|
513
|
+
association_id = record._read_attribute(primary_key)
|
514
|
+
self[foreign_key] = association_id unless self[foreign_key] == association_id
|
515
|
+
end
|
511
516
|
association.loaded!
|
512
517
|
end
|
513
518
|
|
@@ -516,8 +521,20 @@ module ActiveRecord
|
|
516
521
|
end
|
517
522
|
end
|
518
523
|
|
519
|
-
def
|
520
|
-
|
524
|
+
def compute_primary_key(reflection, record)
|
525
|
+
if primary_key_options = reflection.options[:primary_key]
|
526
|
+
primary_key_options
|
527
|
+
elsif reflection.options[:query_constraints] && (query_constraints = record.class.query_constraints_list)
|
528
|
+
query_constraints
|
529
|
+
elsif record.class.has_query_constraints? && !reflection.options[:foreign_key]
|
530
|
+
record.class.query_constraints_list
|
531
|
+
elsif record.class.composite_primary_key?
|
532
|
+
# If record has composite primary key of shape [:<tenant_key>, :id], infer primary_key as :id
|
533
|
+
primary_key = record.class.primary_key
|
534
|
+
primary_key.include?("id") ? "id" : primary_key
|
535
|
+
else
|
536
|
+
record.class.primary_key
|
537
|
+
end
|
521
538
|
end
|
522
539
|
|
523
540
|
def _ensure_no_duplicate_errors
|
data/lib/active_record/base.rb
CHANGED
@@ -12,7 +12,7 @@ require "active_record/attributes"
|
|
12
12
|
require "active_record/type_caster"
|
13
13
|
require "active_record/database_configurations"
|
14
14
|
|
15
|
-
module ActiveRecord
|
15
|
+
module ActiveRecord # :nodoc:
|
16
16
|
# = Active Record
|
17
17
|
#
|
18
18
|
# Active Record objects don't specify their attributes directly, but rather infer them from
|
@@ -137,6 +137,23 @@ module ActiveRecord #:nodoc:
|
|
137
137
|
# anonymous = User.new(name: "")
|
138
138
|
# anonymous.name? # => false
|
139
139
|
#
|
140
|
+
# Query methods will also respect any overrides of default accessors:
|
141
|
+
#
|
142
|
+
# class User
|
143
|
+
# # Has admin boolean column
|
144
|
+
# def admin
|
145
|
+
# false
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# user.update(admin: true)
|
150
|
+
#
|
151
|
+
# user.read_attribute(:admin) # => true, gets the column value
|
152
|
+
# user[:admin] # => true, also gets the column value
|
153
|
+
#
|
154
|
+
# user.admin # => false, due to the getter override
|
155
|
+
# user.admin? # => false, due to the getter override
|
156
|
+
#
|
140
157
|
# == Accessing attributes before they have been typecasted
|
141
158
|
#
|
142
159
|
# Sometimes you want to be able to read the raw attribute data without having the column-determined
|
@@ -216,7 +233,7 @@ module ActiveRecord #:nodoc:
|
|
216
233
|
#
|
217
234
|
# Connections are usually created through
|
218
235
|
# {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] and retrieved
|
219
|
-
# by ActiveRecord::Base.
|
236
|
+
# by ActiveRecord::Base.lease_connection. All classes inheriting from ActiveRecord::Base will use this
|
220
237
|
# connection. But you can also set a class-specific connection. For example, if Course is an
|
221
238
|
# ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
|
222
239
|
# and Course and all of its subclasses will use this connection instead.
|
@@ -263,7 +280,7 @@ module ActiveRecord #:nodoc:
|
|
263
280
|
# So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
|
264
281
|
# instances in the current object space.
|
265
282
|
class Base
|
266
|
-
|
283
|
+
include ActiveModel::API
|
267
284
|
|
268
285
|
extend ActiveSupport::Benchmarkable
|
269
286
|
extend ActiveSupport::DescendantsTracker
|
@@ -287,18 +304,18 @@ module ActiveRecord #:nodoc:
|
|
287
304
|
include Scoping
|
288
305
|
include Sanitization
|
289
306
|
include AttributeAssignment
|
290
|
-
include ActiveModel::Conversion
|
291
307
|
include Integration
|
292
308
|
include Validations
|
293
309
|
include CounterCache
|
294
310
|
include Attributes
|
295
311
|
include Locking::Optimistic
|
296
312
|
include Locking::Pessimistic
|
313
|
+
include Encryption::EncryptableRecord
|
297
314
|
include AttributeMethods
|
298
315
|
include Callbacks
|
299
316
|
include Timestamp
|
300
317
|
include Associations
|
301
|
-
include
|
318
|
+
include SecurePassword
|
302
319
|
include AutosaveAssociation
|
303
320
|
include NestedAttributes
|
304
321
|
include Transactions
|
@@ -308,8 +325,13 @@ module ActiveRecord #:nodoc:
|
|
308
325
|
include Serialization
|
309
326
|
include Store
|
310
327
|
include SecureToken
|
328
|
+
include TokenFor
|
311
329
|
include SignedId
|
312
330
|
include Suppressor
|
331
|
+
include Normalization
|
332
|
+
include Marshalling::Methods
|
333
|
+
|
334
|
+
self.param_delimiter = "_"
|
313
335
|
end
|
314
336
|
|
315
337
|
ActiveSupport.run_load_hooks(:active_record, Base)
|
@@ -84,7 +84,7 @@ module ActiveRecord
|
|
84
84
|
# == Types of callbacks
|
85
85
|
#
|
86
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,
|
87
|
+
# inline methods (using a proc). \Method references and callback objects are the recommended approaches,
|
88
88
|
# inline methods using a proc are sometimes appropriate (such as for creating mix-ins).
|
89
89
|
#
|
90
90
|
# The method reference callbacks work by specifying a protected or private method available in the object, like this:
|
@@ -173,7 +173,7 @@ module ActiveRecord
|
|
173
173
|
#
|
174
174
|
# If a <tt>before_*</tt> callback throws +:abort+, all the later callbacks and
|
175
175
|
# the associated action are cancelled.
|
176
|
-
# Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
|
176
|
+
# \Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
|
177
177
|
# methods on the model, which are called last.
|
178
178
|
#
|
179
179
|
# == Ordering callbacks
|
@@ -224,42 +224,26 @@ module ActiveRecord
|
|
224
224
|
# after_save :do_something_else
|
225
225
|
#
|
226
226
|
# private
|
227
|
+
# def log_children
|
228
|
+
# # Child processing
|
229
|
+
# end
|
227
230
|
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
# def do_something_else
|
233
|
-
# # Something else
|
234
|
-
# end
|
231
|
+
# def do_something_else
|
232
|
+
# # Something else
|
233
|
+
# end
|
235
234
|
# end
|
236
235
|
#
|
237
236
|
# In this case the +log_children+ is executed before +do_something_else+.
|
238
|
-
#
|
237
|
+
# This applies to all non-transactional callbacks, and to +before_commit+.
|
239
238
|
#
|
240
|
-
#
|
241
|
-
#
|
239
|
+
# For transactional +after_+ callbacks (+after_commit+, +after_rollback+, etc), the order
|
240
|
+
# can be set via configuration.
|
242
241
|
#
|
243
|
-
#
|
244
|
-
#
|
245
|
-
# class Topic < ActiveRecord::Base
|
246
|
-
# has_many :children
|
247
|
-
#
|
248
|
-
# after_commit :log_children
|
249
|
-
# after_commit :do_something_else
|
250
|
-
#
|
251
|
-
# private
|
252
|
-
#
|
253
|
-
# def log_children
|
254
|
-
# # Child processing
|
255
|
-
# end
|
256
|
-
#
|
257
|
-
# def do_something_else
|
258
|
-
# # Something else
|
259
|
-
# end
|
260
|
-
# end
|
242
|
+
# config.active_record.run_after_transaction_callbacks_in_order_defined = false
|
261
243
|
#
|
262
|
-
#
|
244
|
+
# When set to +true+ (the default from \Rails 7.1), callbacks are executed in the order they
|
245
|
+
# are defined, just like the example above. When set to +false+, the order is reversed, so
|
246
|
+
# +do_something_else+ is executed before +log_children+.
|
263
247
|
#
|
264
248
|
# == \Transactions
|
265
249
|
#
|
@@ -432,7 +416,7 @@ module ActiveRecord
|
|
432
416
|
define_model_callbacks :save, :create, :update, :destroy
|
433
417
|
end
|
434
418
|
|
435
|
-
def destroy
|
419
|
+
def destroy # :nodoc:
|
436
420
|
@_destroy_callback_already_called ||= false
|
437
421
|
return if @_destroy_callback_already_called
|
438
422
|
@_destroy_callback_already_called = true
|
@@ -444,7 +428,7 @@ module ActiveRecord
|
|
444
428
|
@_destroy_callback_already_called = false
|
445
429
|
end
|
446
430
|
|
447
|
-
def touch(*, **)
|
431
|
+
def touch(*, **) # :nodoc:
|
448
432
|
_run_touch_callbacks { super }
|
449
433
|
end
|
450
434
|
|
@@ -462,7 +446,7 @@ module ActiveRecord
|
|
462
446
|
end
|
463
447
|
|
464
448
|
def _update_record
|
465
|
-
_run_update_callbacks { super }
|
449
|
+
_run_update_callbacks { record_update_timestamps { super } }
|
466
450
|
end
|
467
451
|
end
|
468
452
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Coders # :nodoc:
|
5
|
+
class ColumnSerializer # :nodoc:
|
6
|
+
attr_reader :object_class
|
7
|
+
attr_reader :coder
|
8
|
+
|
9
|
+
def initialize(attr_name, coder, object_class = Object)
|
10
|
+
@attr_name = attr_name
|
11
|
+
@object_class = object_class
|
12
|
+
@coder = coder
|
13
|
+
check_arity_of_constructor
|
14
|
+
end
|
15
|
+
|
16
|
+
def init_with(coder) # :nodoc:
|
17
|
+
@attr_name = coder["attr_name"]
|
18
|
+
@object_class = coder["object_class"]
|
19
|
+
@coder = coder["coder"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def dump(object)
|
23
|
+
return if object.nil?
|
24
|
+
|
25
|
+
assert_valid_value(object, action: "dump")
|
26
|
+
coder.dump(object)
|
27
|
+
end
|
28
|
+
|
29
|
+
def load(payload)
|
30
|
+
if payload.nil?
|
31
|
+
if @object_class != ::Object
|
32
|
+
return @object_class.new
|
33
|
+
end
|
34
|
+
return nil
|
35
|
+
end
|
36
|
+
|
37
|
+
object = coder.load(payload)
|
38
|
+
|
39
|
+
assert_valid_value(object, action: "load")
|
40
|
+
object ||= object_class.new if object_class != Object
|
41
|
+
|
42
|
+
object
|
43
|
+
end
|
44
|
+
|
45
|
+
# Public because it's called by Type::Serialized
|
46
|
+
def assert_valid_value(object, action:)
|
47
|
+
unless object.nil? || object_class === object
|
48
|
+
raise SerializationTypeMismatch,
|
49
|
+
"can't #{action} `#{@attr_name}`: was supposed to be a #{object_class}, but was a #{object.class}. -- #{object.inspect}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def check_arity_of_constructor
|
55
|
+
load(nil)
|
56
|
+
rescue ArgumentError
|
57
|
+
raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -4,37 +4,83 @@ require "yaml"
|
|
4
4
|
|
5
5
|
module ActiveRecord
|
6
6
|
module Coders # :nodoc:
|
7
|
-
class YAMLColumn # :nodoc:
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
check_arity_of_constructor
|
14
|
-
end
|
7
|
+
class YAMLColumn < ColumnSerializer # :nodoc:
|
8
|
+
class SafeCoder
|
9
|
+
def initialize(permitted_classes: [], unsafe_load: nil)
|
10
|
+
@permitted_classes = permitted_classes
|
11
|
+
@unsafe_load = unsafe_load
|
12
|
+
end
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
if Gem::Version.new(Psych::VERSION) >= Gem::Version.new("5.1")
|
15
|
+
def dump(object)
|
16
|
+
if @unsafe_load.nil? ? ActiveRecord.use_yaml_unsafe_load : @unsafe_load
|
17
|
+
::YAML.dump(object)
|
18
|
+
else
|
19
|
+
::YAML.safe_dump(
|
20
|
+
object,
|
21
|
+
permitted_classes: @permitted_classes + ActiveRecord.yaml_column_permitted_classes,
|
22
|
+
aliases: true,
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
else
|
27
|
+
def dump(object)
|
28
|
+
YAML.dump(object)
|
29
|
+
end
|
30
|
+
end
|
18
31
|
|
19
|
-
|
20
|
-
|
32
|
+
if YAML.respond_to?(:unsafe_load)
|
33
|
+
def load(payload)
|
34
|
+
if @unsafe_load.nil? ? ActiveRecord.use_yaml_unsafe_load : @unsafe_load
|
35
|
+
YAML.unsafe_load(payload)
|
36
|
+
else
|
37
|
+
YAML.safe_load(
|
38
|
+
payload,
|
39
|
+
permitted_classes: @permitted_classes + ActiveRecord.yaml_column_permitted_classes,
|
40
|
+
aliases: true,
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
else
|
45
|
+
def load(payload)
|
46
|
+
if @unsafe_load.nil? ? ActiveRecord.use_yaml_unsafe_load : @unsafe_load
|
47
|
+
YAML.load(payload)
|
48
|
+
else
|
49
|
+
YAML.safe_load(
|
50
|
+
payload,
|
51
|
+
permitted_classes: @permitted_classes + ActiveRecord.yaml_column_permitted_classes,
|
52
|
+
aliases: true,
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
21
57
|
end
|
22
58
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
59
|
+
def initialize(attr_name, object_class = Object, permitted_classes: [], unsafe_load: nil)
|
60
|
+
super(
|
61
|
+
attr_name,
|
62
|
+
SafeCoder.new(permitted_classes: permitted_classes || [], unsafe_load: unsafe_load),
|
63
|
+
object_class,
|
64
|
+
)
|
65
|
+
check_arity_of_constructor
|
66
|
+
end
|
30
67
|
|
31
|
-
|
68
|
+
def init_with(coder) # :nodoc:
|
69
|
+
unless coder["coder"]
|
70
|
+
permitted_classes = coder["permitted_classes"] || []
|
71
|
+
unsafe_load = coder["unsafe_load"] || false
|
72
|
+
coder["coder"] = SafeCoder.new(permitted_classes: permitted_classes, unsafe_load: unsafe_load)
|
73
|
+
end
|
74
|
+
super(coder)
|
32
75
|
end
|
33
76
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
77
|
+
def coder
|
78
|
+
# This is to retain forward compatibility when loading records serialized with Marshal
|
79
|
+
# from a previous version of Rails.
|
80
|
+
@coder ||= begin
|
81
|
+
permitted_classes = defined?(@permitted_classes) ? @permitted_classes : []
|
82
|
+
unsafe_load = defined?(@unsafe_load) && @unsafe_load.nil?
|
83
|
+
SafeCoder.new(permitted_classes: permitted_classes, unsafe_load: unsafe_load)
|
38
84
|
end
|
39
85
|
end
|
40
86
|
|
@@ -44,28 +90,6 @@ module ActiveRecord
|
|
44
90
|
rescue ArgumentError
|
45
91
|
raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
|
46
92
|
end
|
47
|
-
|
48
|
-
if YAML.respond_to?(:unsafe_load)
|
49
|
-
def yaml_load(payload)
|
50
|
-
if ActiveRecord::Base.use_yaml_unsafe_load
|
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)
|
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
|
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)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
93
|
end
|
70
94
|
end
|
71
95
|
end
|