activerecord 6.1.7 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1516 -1019
- data/MIT-LICENSE +1 -1
- data/README.rdoc +17 -18
- data/lib/active_record/aggregations.rb +17 -14
- data/lib/active_record/association_relation.rb +1 -11
- data/lib/active_record/associations/association.rb +50 -19
- data/lib/active_record/associations/association_scope.rb +17 -12
- data/lib/active_record/associations/belongs_to_association.rb +28 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +11 -5
- data/lib/active_record/associations/builder/belongs_to.rb +40 -14
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +6 -2
- data/lib/active_record/associations/collection_association.rb +35 -31
- data/lib/active_record/associations/collection_proxy.rb +30 -15
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +28 -18
- 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.rb +26 -16
- data/lib/active_record/associations/preloader/association.rb +207 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +50 -14
- data/lib/active_record/associations/preloader.rb +50 -121
- data/lib/active_record/associations/singular_association.rb +9 -3
- data/lib/active_record/associations/through_association.rb +25 -14
- data/lib/active_record/associations.rb +423 -289
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
- data/lib/active_record/attribute_methods/dirty.rb +61 -14
- data/lib/active_record/attribute_methods/primary_key.rb +78 -26
- data/lib/active_record/attribute_methods/query.rb +31 -19
- data/lib/active_record/attribute_methods/read.rb +25 -10
- data/lib/active_record/attribute_methods/serialization.rb +194 -37
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +10 -13
- data/lib/active_record/attribute_methods.rb +121 -40
- data/lib/active_record/attributes.rb +27 -38
- data/lib/active_record/autosave_association.rb +61 -30
- data/lib/active_record/base.rb +25 -2
- 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 +367 -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 +78 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +96 -590
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -51
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +77 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
- 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 +360 -136
- data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
- data/lib/active_record/connection_adapters/abstract_adapter.rb +622 -149
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +285 -156
- 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 +25 -134
- data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
- 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 +38 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +104 -53
- data/lib/active_record/connection_adapters/pool_config.rb +20 -11
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +18 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +86 -52
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- 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/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.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
- 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 +153 -3
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +381 -69
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +492 -230
- data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +65 -53
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +294 -102
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
- data/lib/active_record/connection_adapters.rb +9 -6
- data/lib/active_record/connection_handling.rb +107 -136
- data/lib/active_record/core.rb +194 -224
- data/lib/active_record/counter_cache.rb +46 -25
- data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
- data/lib/active_record/database_configurations/database_config.rb +21 -12
- data/lib/active_record/database_configurations/hash_config.rb +84 -16
- data/lib/active_record/database_configurations/url_config.rb +18 -12
- data/lib/active_record/database_configurations.rb +95 -59
- data/lib/active_record/delegated_type.rb +61 -15
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- 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 +224 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +151 -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 +155 -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 +172 -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_serializer.rb +92 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +96 -0
- data/lib/active_record/encryption.rb +56 -0
- data/lib/active_record/enum.rb +156 -62
- data/lib/active_record/errors.rb +171 -15
- data/lib/active_record/explain.rb +23 -3
- 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 +131 -86
- data/lib/active_record/future_result.rb +164 -0
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +81 -29
- data/lib/active_record/insert_all.rb +133 -20
- data/lib/active_record/integration.rb +11 -10
- data/lib/active_record/internal_metadata.rb +117 -33
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +36 -21
- data/lib/active_record/locking/pessimistic.rb +15 -6
- data/lib/active_record/log_subscriber.rb +52 -19
- 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 +108 -13
- data/lib/active_record/migration/compatibility.rb +221 -48
- data/lib/active_record/migration/default_strategy.rb +23 -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.rb +355 -171
- data/lib/active_record/model_schema.rb +116 -97
- data/lib/active_record/nested_attributes.rb +36 -15
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/normalization.rb +159 -0
- data/lib/active_record/persistence.rb +405 -85
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +3 -21
- data/lib/active_record/query_logs.rb +174 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +29 -6
- data/lib/active_record/railtie.rb +219 -43
- data/lib/active_record/railties/controller_runtime.rb +13 -9
- data/lib/active_record/railties/databases.rake +185 -249
- 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 +229 -80
- data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
- data/lib/active_record/relation/batches.rb +192 -63
- data/lib/active_record/relation/calculations.rb +211 -90
- data/lib/active_record/relation/delegation.rb +27 -13
- data/lib/active_record/relation/finder_methods.rb +108 -51
- data/lib/active_record/relation/merger.rb +22 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +27 -20
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +654 -127
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +20 -3
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +262 -120
- data/lib/active_record/result.rb +37 -11
- data/lib/active_record/runtime_registry.rb +18 -13
- data/lib/active_record/sanitization.rb +65 -20
- data/lib/active_record/schema.rb +36 -22
- data/lib/active_record/schema_dumper.rb +73 -24
- data/lib/active_record/schema_migration.rb +68 -33
- 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 +10 -8
- data/lib/active_record/store.rb +10 -10
- data/lib/active_record/suppressor.rb +13 -15
- data/lib/active_record/table_metadata.rb +16 -3
- data/lib/active_record/tasks/database_tasks.rb +225 -136
- 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 +15 -7
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +116 -96
- data/lib/active_record/timestamp.rb +28 -17
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +48 -27
- data/lib/active_record/translation.rb +3 -3
- 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 -5
- 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/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +4 -4
- 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 +51 -6
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +335 -32
- data/lib/arel/attributes/attribute.rb +0 -8
- 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/and.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -1
- data/lib/arel/nodes/bound_sql_literal.rb +61 -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 +0 -8
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- 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 +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +5 -0
- data/lib/arel/predications.rb +13 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +9 -6
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +16 -3
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +139 -19
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +18 -3
- 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.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 +92 -13
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -67
@@ -9,9 +9,6 @@ module ActiveRecord
|
|
9
9
|
ON_ERROR_STOP_1 = "ON_ERROR_STOP=1"
|
10
10
|
SQL_COMMENT_BEGIN = "--"
|
11
11
|
|
12
|
-
delegate :connection, :establish_connection, :clear_active_connections!,
|
13
|
-
to: ActiveRecord::Base
|
14
|
-
|
15
12
|
def self.using_database_configurations?
|
16
13
|
true
|
17
14
|
end
|
@@ -21,14 +18,14 @@ module ActiveRecord
|
|
21
18
|
@configuration_hash = db_config.configuration_hash
|
22
19
|
end
|
23
20
|
|
24
|
-
def create(
|
25
|
-
|
21
|
+
def create(connection_already_established = false)
|
22
|
+
establish_connection(public_schema_config) unless connection_already_established
|
26
23
|
connection.create_database(db_config.database, configuration_hash.merge(encoding: encoding))
|
27
|
-
establish_connection
|
24
|
+
establish_connection
|
28
25
|
end
|
29
26
|
|
30
27
|
def drop
|
31
|
-
|
28
|
+
establish_connection(public_schema_config)
|
32
29
|
connection.drop_database(db_config.database)
|
33
30
|
end
|
34
31
|
|
@@ -41,26 +38,27 @@ module ActiveRecord
|
|
41
38
|
end
|
42
39
|
|
43
40
|
def purge
|
44
|
-
clear_active_connections!
|
41
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
|
45
42
|
drop
|
46
43
|
create true
|
47
44
|
end
|
48
45
|
|
49
46
|
def structure_dump(filename, extra_flags)
|
50
|
-
set_psql_env
|
51
|
-
|
52
47
|
search_path = \
|
53
|
-
case ActiveRecord
|
48
|
+
case ActiveRecord.dump_schemas
|
54
49
|
when :schema_search_path
|
55
50
|
configuration_hash[:schema_search_path]
|
56
51
|
when :all
|
57
52
|
nil
|
58
53
|
when String
|
59
|
-
ActiveRecord
|
54
|
+
ActiveRecord.dump_schemas
|
60
55
|
end
|
61
56
|
|
62
|
-
args = ["--schema-only", "--no-privileges", "--no-owner"
|
57
|
+
args = ["--schema-only", "--no-privileges", "--no-owner"]
|
58
|
+
args.concat(["--file", filename])
|
59
|
+
|
63
60
|
args.concat(Array(extra_flags)) if extra_flags
|
61
|
+
|
64
62
|
unless search_path.blank?
|
65
63
|
args += search_path.split(",").map do |part|
|
66
64
|
"--schema=#{part.strip}"
|
@@ -69,6 +67,7 @@ module ActiveRecord
|
|
69
67
|
|
70
68
|
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
71
69
|
if ignore_tables.any?
|
70
|
+
ignore_tables = connection.data_sources.select { |table| ignore_tables.any? { |pattern| pattern === table } }
|
72
71
|
args += ignore_tables.flat_map { |table| ["-T", table] }
|
73
72
|
end
|
74
73
|
|
@@ -79,8 +78,7 @@ module ActiveRecord
|
|
79
78
|
end
|
80
79
|
|
81
80
|
def structure_load(filename, extra_flags)
|
82
|
-
|
83
|
-
args = ["--set", ON_ERROR_STOP_1, "--quiet", "--no-psqlrc", "--file", filename]
|
81
|
+
args = ["--set", ON_ERROR_STOP_1, "--quiet", "--no-psqlrc", "--output", File::NULL, "--file", filename]
|
84
82
|
args.concat(Array(extra_flags)) if extra_flags
|
85
83
|
args << db_config.database
|
86
84
|
run_cmd("psql", args, "loading")
|
@@ -89,26 +87,37 @@ module ActiveRecord
|
|
89
87
|
private
|
90
88
|
attr_reader :db_config, :configuration_hash
|
91
89
|
|
90
|
+
def connection
|
91
|
+
ActiveRecord::Base.connection
|
92
|
+
end
|
93
|
+
|
94
|
+
def establish_connection(config = db_config)
|
95
|
+
ActiveRecord::Base.establish_connection(config)
|
96
|
+
end
|
97
|
+
|
92
98
|
def encoding
|
93
99
|
configuration_hash[:encoding] || DEFAULT_ENCODING
|
94
100
|
end
|
95
101
|
|
96
|
-
def
|
97
|
-
|
98
|
-
database: "postgres",
|
99
|
-
schema_search_path: "public"
|
100
|
-
)
|
102
|
+
def public_schema_config
|
103
|
+
configuration_hash.merge(database: "postgres", schema_search_path: "public")
|
101
104
|
end
|
102
105
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
106
|
+
def psql_env
|
107
|
+
{}.tap do |env|
|
108
|
+
env["PGHOST"] = db_config.host if db_config.host
|
109
|
+
env["PGPORT"] = configuration_hash[:port].to_s if configuration_hash[:port]
|
110
|
+
env["PGPASSWORD"] = configuration_hash[:password].to_s if configuration_hash[:password]
|
111
|
+
env["PGUSER"] = configuration_hash[:username].to_s if configuration_hash[:username]
|
112
|
+
env["PGSSLMODE"] = configuration_hash[:sslmode].to_s if configuration_hash[:sslmode]
|
113
|
+
env["PGSSLCERT"] = configuration_hash[:sslcert].to_s if configuration_hash[:sslcert]
|
114
|
+
env["PGSSLKEY"] = configuration_hash[:sslkey].to_s if configuration_hash[:sslkey]
|
115
|
+
env["PGSSLROOTCERT"] = configuration_hash[:sslrootcert].to_s if configuration_hash[:sslrootcert]
|
116
|
+
end
|
108
117
|
end
|
109
118
|
|
110
119
|
def run_cmd(cmd, args, action)
|
111
|
-
fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
|
120
|
+
fail run_cmd_error(cmd, args, action) unless Kernel.system(psql_env, cmd, *args)
|
112
121
|
end
|
113
122
|
|
114
123
|
def run_cmd_error(cmd, args, action)
|
@@ -3,8 +3,6 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Tasks # :nodoc:
|
5
5
|
class SQLiteDatabaseTasks # :nodoc:
|
6
|
-
delegate :connection, :establish_connection, to: ActiveRecord::Base
|
7
|
-
|
8
6
|
def self.using_database_configurations?
|
9
7
|
true
|
10
8
|
end
|
@@ -17,25 +15,26 @@ module ActiveRecord
|
|
17
15
|
def create
|
18
16
|
raise DatabaseAlreadyExists if File.exist?(db_config.database)
|
19
17
|
|
20
|
-
establish_connection
|
18
|
+
establish_connection
|
21
19
|
connection
|
22
20
|
end
|
23
21
|
|
24
22
|
def drop
|
25
|
-
|
26
|
-
|
27
|
-
file = path.absolute? ? path.to_s : File.join(root, path)
|
28
|
-
|
23
|
+
db_path = db_config.database
|
24
|
+
file = File.absolute_path?(db_path) ? db_path : File.join(root, db_path)
|
29
25
|
FileUtils.rm(file)
|
26
|
+
FileUtils.rm_f(["#{file}-shm", "#{file}-wal"])
|
30
27
|
rescue Errno::ENOENT => error
|
31
28
|
raise NoDatabaseError.new(error.message)
|
32
29
|
end
|
33
30
|
|
34
31
|
def purge
|
32
|
+
connection.disconnect!
|
35
33
|
drop
|
36
34
|
rescue NoDatabaseError
|
37
35
|
ensure
|
38
36
|
create
|
37
|
+
connection.reconnect!
|
39
38
|
end
|
40
39
|
|
41
40
|
def charset
|
@@ -49,6 +48,7 @@ module ActiveRecord
|
|
49
48
|
|
50
49
|
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
51
50
|
if ignore_tables.any?
|
51
|
+
ignore_tables = connection.data_sources.select { |table| ignore_tables.any? { |pattern| pattern === table } }
|
52
52
|
condition = ignore_tables.map { |table| connection.quote(table) }.join(", ")
|
53
53
|
args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
|
54
54
|
else
|
@@ -65,6 +65,14 @@ module ActiveRecord
|
|
65
65
|
private
|
66
66
|
attr_reader :db_config, :root
|
67
67
|
|
68
|
+
def connection
|
69
|
+
ActiveRecord::Base.connection
|
70
|
+
end
|
71
|
+
|
72
|
+
def establish_connection(config = db_config)
|
73
|
+
ActiveRecord::Base.establish_connection(config)
|
74
|
+
end
|
75
|
+
|
68
76
|
def run_cmd(cmd, args, out)
|
69
77
|
fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out)
|
70
78
|
end
|
@@ -14,7 +14,7 @@ module ActiveRecord
|
|
14
14
|
ActiveRecord::Base.configurations.configs_for(env_name: env_name).each do |db_config|
|
15
15
|
db_config._database = "#{db_config.database}-#{i}"
|
16
16
|
|
17
|
-
ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config, ActiveRecord
|
17
|
+
ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config, ActiveRecord.schema_format, nil)
|
18
18
|
end
|
19
19
|
ensure
|
20
20
|
ActiveRecord::Base.establish_connection
|
@@ -17,13 +17,26 @@ module ActiveRecord
|
|
17
17
|
end
|
18
18
|
|
19
19
|
included do
|
20
|
-
|
20
|
+
##
|
21
|
+
# :singleton-method: fixture_paths
|
22
|
+
#
|
23
|
+
# Returns the ActiveRecord::FixtureSet collection
|
24
|
+
|
25
|
+
##
|
26
|
+
# :singleton-method: fixture_paths=
|
27
|
+
#
|
28
|
+
# :call-seq:
|
29
|
+
# fixture_paths=(fixture_paths)
|
30
|
+
class_attribute :fixture_paths, instance_writer: false, default: []
|
21
31
|
class_attribute :fixture_table_names, default: []
|
22
32
|
class_attribute :fixture_class_names, default: {}
|
23
33
|
class_attribute :use_transactional_tests, default: true
|
24
34
|
class_attribute :use_instantiated_fixtures, default: false # true, false, or :no_instances
|
25
35
|
class_attribute :pre_loaded_fixtures, default: false
|
26
36
|
class_attribute :lock_threads, default: true
|
37
|
+
class_attribute :fixture_sets, default: {}
|
38
|
+
|
39
|
+
ActiveSupport.run_load_hooks(:active_record_fixtures, self)
|
27
40
|
end
|
28
41
|
|
29
42
|
module ClassMethods
|
@@ -39,12 +52,28 @@ module ActiveRecord
|
|
39
52
|
self.fixture_class_names = fixture_class_names.merge(class_names.stringify_keys)
|
40
53
|
end
|
41
54
|
|
55
|
+
def fixture_path # :nodoc:
|
56
|
+
ActiveRecord.deprecator.warn(<<~WARNING)
|
57
|
+
TestFixtures.fixture_path is deprecated and will be removed in Rails 7.2. Use .fixture_paths instead.
|
58
|
+
If multiple fixture paths have been configured with .fixture_paths, then .fixture_path will just return
|
59
|
+
the first path.
|
60
|
+
WARNING
|
61
|
+
fixture_paths.first
|
62
|
+
end
|
63
|
+
|
64
|
+
def fixture_path=(path) # :nodoc:
|
65
|
+
ActiveRecord.deprecator.warn("TestFixtures.fixture_path= is deprecated and will be removed in Rails 7.2. Use .fixture_paths= instead.")
|
66
|
+
self.fixture_paths = Array(path)
|
67
|
+
end
|
68
|
+
|
42
69
|
def fixtures(*fixture_set_names)
|
43
70
|
if fixture_set_names.first == :all
|
44
|
-
raise StandardError, "No fixture path found. Please set `#{self}.
|
45
|
-
fixture_set_names =
|
46
|
-
|
47
|
-
|
71
|
+
raise StandardError, "No fixture path found. Please set `#{self}.fixture_paths`." if fixture_paths.blank?
|
72
|
+
fixture_set_names = fixture_paths.flat_map do |path|
|
73
|
+
names = Dir[::File.join(path, "{**,*}/*.{yml}")].uniq
|
74
|
+
names.reject! { |f| f.start_with?(file_fixture_path.to_s) } if defined?(file_fixture_path) && file_fixture_path
|
75
|
+
names.map! { |f| f[path.to_s.size..-5].delete_prefix("/") }
|
76
|
+
end.uniq
|
48
77
|
else
|
49
78
|
fixture_set_names = fixture_set_names.flatten.map(&:to_s)
|
50
79
|
end
|
@@ -55,37 +84,20 @@ module ActiveRecord
|
|
55
84
|
|
56
85
|
def setup_fixture_accessors(fixture_set_names = nil)
|
57
86
|
fixture_set_names = Array(fixture_set_names || fixture_table_names)
|
58
|
-
|
87
|
+
unless fixture_set_names.empty?
|
88
|
+
self.fixture_sets = fixture_sets.dup
|
59
89
|
fixture_set_names.each do |fs_name|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
|
65
|
-
return_single_record = fixture_names.size == 1
|
66
|
-
fixture_names = @loaded_fixtures[fs_name].fixtures.keys if fixture_names.empty?
|
67
|
-
|
68
|
-
@fixture_cache[fs_name] ||= {}
|
69
|
-
|
70
|
-
instances = fixture_names.map do |f_name|
|
71
|
-
f_name = f_name.to_s if f_name.is_a?(Symbol)
|
72
|
-
@fixture_cache[fs_name].delete(f_name) if force_reload
|
73
|
-
|
74
|
-
if @loaded_fixtures[fs_name][f_name]
|
75
|
-
@fixture_cache[fs_name][f_name] ||= @loaded_fixtures[fs_name][f_name].find
|
76
|
-
else
|
77
|
-
raise StandardError, "No fixture named '#{f_name}' found for fixture set '#{fs_name}'"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
return_single_record ? instances.first : instances
|
82
|
-
end
|
83
|
-
private accessor_name
|
90
|
+
key = fs_name.to_s.include?("/") ? -fs_name.to_s.tr("/", "_") : fs_name
|
91
|
+
key = -key.to_s if key.is_a?(Symbol)
|
92
|
+
fs_name = -fs_name.to_s if fs_name.is_a?(Symbol)
|
93
|
+
fixture_sets[key] = fs_name
|
84
94
|
end
|
85
95
|
end
|
86
|
-
include methods
|
87
96
|
end
|
88
97
|
|
98
|
+
# Prevents automatically wrapping each specified test in a transaction,
|
99
|
+
# to allow application logic transactions to be tested in a top-level
|
100
|
+
# (non-nested) context.
|
89
101
|
def uses_transaction(*methods)
|
90
102
|
@uses_transaction = [] unless defined?(@uses_transaction)
|
91
103
|
@uses_transaction.concat methods.map(&:to_s)
|
@@ -97,6 +109,15 @@ module ActiveRecord
|
|
97
109
|
end
|
98
110
|
end
|
99
111
|
|
112
|
+
def fixture_path # :nodoc:
|
113
|
+
ActiveRecord.deprecator.warn(<<~WARNING)
|
114
|
+
TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2. Use #fixture_paths instead.
|
115
|
+
If multiple fixture paths have been configured with #fixture_paths, then #fixture_path will just return
|
116
|
+
the first path.
|
117
|
+
WARNING
|
118
|
+
fixture_paths.first
|
119
|
+
end
|
120
|
+
|
100
121
|
def run_in_transaction?
|
101
122
|
use_transactional_tests &&
|
102
123
|
!self.class.uses_transaction?(name)
|
@@ -111,7 +132,6 @@ module ActiveRecord
|
|
111
132
|
@fixture_connections = []
|
112
133
|
@@already_loaded_fixtures ||= {}
|
113
134
|
@connection_subscriber = nil
|
114
|
-
@legacy_saved_pool_configs = Hash.new { |hash, key| hash[key] = {} }
|
115
135
|
@saved_pool_configs = Hash.new { |hash, key| hash[key] = {} }
|
116
136
|
|
117
137
|
# Load fixtures once and begin transaction.
|
@@ -132,19 +152,18 @@ module ActiveRecord
|
|
132
152
|
|
133
153
|
# When connections are established in the future, begin a transaction too
|
134
154
|
@connection_subscriber = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
|
135
|
-
|
155
|
+
connection_name = payload[:connection_name] if payload.key?(:connection_name)
|
136
156
|
shard = payload[:shard] if payload.key?(:shard)
|
137
|
-
setup_shared_connection_pool if ActiveRecord::Base.legacy_connection_handling
|
138
157
|
|
139
|
-
if
|
158
|
+
if connection_name
|
140
159
|
begin
|
141
|
-
connection = ActiveRecord::Base.connection_handler.retrieve_connection(
|
160
|
+
connection = ActiveRecord::Base.connection_handler.retrieve_connection(connection_name, shard: shard)
|
142
161
|
rescue ConnectionNotEstablished
|
143
162
|
connection = nil
|
144
163
|
end
|
145
164
|
|
146
165
|
if connection
|
147
|
-
setup_shared_connection_pool
|
166
|
+
setup_shared_connection_pool
|
148
167
|
|
149
168
|
if !@fixture_connections.include?(connection)
|
150
169
|
connection.begin_transaction joinable: false, _lazy: false
|
@@ -180,13 +199,13 @@ module ActiveRecord
|
|
180
199
|
ActiveRecord::FixtureSet.reset_cache
|
181
200
|
end
|
182
201
|
|
183
|
-
ActiveRecord::Base.clear_active_connections!
|
202
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
|
184
203
|
end
|
185
204
|
|
186
205
|
def enlist_fixture_connections
|
187
206
|
setup_shared_connection_pool
|
188
207
|
|
189
|
-
ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
|
208
|
+
ActiveRecord::Base.connection_handler.connection_pool_list(:writing).map(&:connection)
|
190
209
|
end
|
191
210
|
|
192
211
|
private
|
@@ -197,79 +216,43 @@ module ActiveRecord
|
|
197
216
|
# need to share a connection pool so that the reading connection
|
198
217
|
# can see data in the open transaction on the writing connection.
|
199
218
|
def setup_shared_connection_pool
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
pool_config = pool_manager.get_pool_config(nil, shard_name)
|
214
|
-
next if pool_config == writing_pool_config
|
215
|
-
|
216
|
-
@legacy_saved_pool_configs[handler][name][shard_name] = pool_config
|
217
|
-
pool_manager.set_pool_config(nil, shard_name, writing_pool_config)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
else
|
223
|
-
handler = ActiveRecord::Base.connection_handler
|
224
|
-
|
225
|
-
handler.connection_pool_names.each do |name|
|
226
|
-
pool_manager = handler.send(:owner_to_pool_manager)[name]
|
227
|
-
pool_manager.shard_names.each do |shard_name|
|
228
|
-
writing_pool_config = pool_manager.get_pool_config(ActiveRecord::Base.writing_role, shard_name)
|
229
|
-
@saved_pool_configs[name][shard_name] ||= {}
|
230
|
-
pool_manager.role_names.each do |role|
|
231
|
-
next unless pool_config = pool_manager.get_pool_config(role, shard_name)
|
232
|
-
next if pool_config == writing_pool_config
|
233
|
-
|
234
|
-
@saved_pool_configs[name][shard_name][role] = pool_config
|
235
|
-
pool_manager.set_pool_config(role, shard_name, writing_pool_config)
|
236
|
-
end
|
219
|
+
handler = ActiveRecord::Base.connection_handler
|
220
|
+
|
221
|
+
handler.connection_pool_names.each do |name|
|
222
|
+
pool_manager = handler.send(:connection_name_to_pool_manager)[name]
|
223
|
+
pool_manager.shard_names.each do |shard_name|
|
224
|
+
writing_pool_config = pool_manager.get_pool_config(ActiveRecord.writing_role, shard_name)
|
225
|
+
@saved_pool_configs[name][shard_name] ||= {}
|
226
|
+
pool_manager.role_names.each do |role|
|
227
|
+
next unless pool_config = pool_manager.get_pool_config(role, shard_name)
|
228
|
+
next if pool_config == writing_pool_config
|
229
|
+
|
230
|
+
@saved_pool_configs[name][shard_name][role] = pool_config
|
231
|
+
pool_manager.set_pool_config(role, shard_name, writing_pool_config)
|
237
232
|
end
|
238
233
|
end
|
239
234
|
end
|
240
235
|
end
|
241
236
|
|
242
237
|
def teardown_shared_connection_pool
|
243
|
-
|
244
|
-
@legacy_saved_pool_configs.each_pair do |handler, names|
|
245
|
-
names.each_pair do |name, shards|
|
246
|
-
shards.each_pair do |shard_name, pool_config|
|
247
|
-
pool_manager = handler.send(:owner_to_pool_manager)[name]
|
248
|
-
pool_manager.set_pool_config(nil, shard_name, pool_config)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
else
|
253
|
-
handler = ActiveRecord::Base.connection_handler
|
238
|
+
handler = ActiveRecord::Base.connection_handler
|
254
239
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
240
|
+
@saved_pool_configs.each_pair do |name, shards|
|
241
|
+
pool_manager = handler.send(:connection_name_to_pool_manager)[name]
|
242
|
+
shards.each_pair do |shard_name, roles|
|
243
|
+
roles.each_pair do |role, pool_config|
|
244
|
+
next unless pool_manager.get_pool_config(role, shard_name)
|
260
245
|
|
261
|
-
|
262
|
-
end
|
246
|
+
pool_manager.set_pool_config(role, shard_name, pool_config)
|
263
247
|
end
|
264
248
|
end
|
265
249
|
end
|
266
250
|
|
267
|
-
@legacy_saved_pool_configs.clear
|
268
251
|
@saved_pool_configs.clear
|
269
252
|
end
|
270
253
|
|
271
254
|
def load_fixtures(config)
|
272
|
-
ActiveRecord::FixtureSet.create_fixtures(
|
255
|
+
ActiveRecord::FixtureSet.create_fixtures(fixture_paths, fixture_table_names, fixture_class_names, config).index_by(&:name)
|
273
256
|
end
|
274
257
|
|
275
258
|
def instantiate_fixtures
|
@@ -287,5 +270,42 @@ module ActiveRecord
|
|
287
270
|
def load_instances?
|
288
271
|
use_instantiated_fixtures != :no_instances
|
289
272
|
end
|
273
|
+
|
274
|
+
def method_missing(name, *args, **kwargs, &block)
|
275
|
+
if fs_name = fixture_sets[name.to_s]
|
276
|
+
access_fixture(fs_name, *args, **kwargs, &block)
|
277
|
+
else
|
278
|
+
super
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def respond_to_missing?(name, include_private = false)
|
283
|
+
if include_private && fixture_sets.key?(name.to_s)
|
284
|
+
true
|
285
|
+
else
|
286
|
+
super
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def access_fixture(fs_name, *fixture_names)
|
291
|
+
force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
|
292
|
+
return_single_record = fixture_names.size == 1
|
293
|
+
|
294
|
+
fixture_names = @loaded_fixtures[fs_name].fixtures.keys if fixture_names.empty?
|
295
|
+
@fixture_cache[fs_name] ||= {}
|
296
|
+
|
297
|
+
instances = fixture_names.map do |f_name|
|
298
|
+
f_name = f_name.to_s if f_name.is_a?(Symbol)
|
299
|
+
@fixture_cache[fs_name].delete(f_name) if force_reload
|
300
|
+
|
301
|
+
if @loaded_fixtures[fs_name][f_name]
|
302
|
+
@fixture_cache[fs_name][f_name] ||= @loaded_fixtures[fs_name][f_name].find
|
303
|
+
else
|
304
|
+
raise StandardError, "No fixture named '#{f_name}' found for fixture set '#{fs_name}'"
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
return_single_record ? instances.first : instances
|
309
|
+
end
|
290
310
|
end
|
291
311
|
end
|
@@ -75,9 +75,17 @@ module ActiveRecord
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def current_time_from_proper_timezone
|
78
|
-
default_timezone == :utc ? Time.now.utc : Time.now
|
78
|
+
connection.default_timezone == :utc ? Time.now.utc : Time.now
|
79
79
|
end
|
80
80
|
|
81
|
+
protected
|
82
|
+
def reload_schema_from_cache(recursive = true)
|
83
|
+
@timestamp_attributes_for_create_in_model = nil
|
84
|
+
@timestamp_attributes_for_update_in_model = nil
|
85
|
+
@all_timestamp_attributes_in_model = nil
|
86
|
+
super
|
87
|
+
end
|
88
|
+
|
81
89
|
private
|
82
90
|
def timestamp_attributes_for_create
|
83
91
|
["created_at", "created_on"].map! { |name| attribute_aliases[name] || name }
|
@@ -86,16 +94,14 @@ module ActiveRecord
|
|
86
94
|
def timestamp_attributes_for_update
|
87
95
|
["updated_at", "updated_on"].map! { |name| attribute_aliases[name] || name }
|
88
96
|
end
|
89
|
-
|
90
|
-
def reload_schema_from_cache
|
91
|
-
@timestamp_attributes_for_create_in_model = nil
|
92
|
-
@timestamp_attributes_for_update_in_model = nil
|
93
|
-
@all_timestamp_attributes_in_model = nil
|
94
|
-
super
|
95
|
-
end
|
96
97
|
end
|
97
98
|
|
98
99
|
private
|
100
|
+
def init_internals
|
101
|
+
super
|
102
|
+
@_touch_record = nil
|
103
|
+
end
|
104
|
+
|
99
105
|
def _create_record
|
100
106
|
if record_timestamps
|
101
107
|
current_time = current_time_from_proper_timezone
|
@@ -109,6 +115,17 @@ module ActiveRecord
|
|
109
115
|
end
|
110
116
|
|
111
117
|
def _update_record
|
118
|
+
record_update_timestamps
|
119
|
+
|
120
|
+
super
|
121
|
+
end
|
122
|
+
|
123
|
+
def create_or_update(touch: true, **)
|
124
|
+
@_touch_record = touch
|
125
|
+
super
|
126
|
+
end
|
127
|
+
|
128
|
+
def record_update_timestamps
|
112
129
|
if @_touch_record && should_record_timestamps?
|
113
130
|
current_time = current_time_from_proper_timezone
|
114
131
|
|
@@ -118,16 +135,11 @@ module ActiveRecord
|
|
118
135
|
end
|
119
136
|
end
|
120
137
|
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
def create_or_update(touch: true, **)
|
125
|
-
@_touch_record = touch
|
126
|
-
super
|
138
|
+
yield if block_given?
|
127
139
|
end
|
128
140
|
|
129
141
|
def should_record_timestamps?
|
130
|
-
record_timestamps && (!
|
142
|
+
record_timestamps && (!partial_updates? || has_changes_to_save?)
|
131
143
|
end
|
132
144
|
|
133
145
|
def timestamp_attributes_for_create_in_model
|
@@ -148,8 +160,7 @@ module ActiveRecord
|
|
148
160
|
|
149
161
|
def max_updated_column_timestamp
|
150
162
|
timestamp_attributes_for_update_in_model
|
151
|
-
.
|
152
|
-
.compact
|
163
|
+
.filter_map { |attr| self[attr]&.to_time }
|
153
164
|
.max
|
154
165
|
end
|
155
166
|
|