activerecord 6.1.7.10 → 7.0.0.alpha1
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.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +726 -1404
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +0 -10
- data/lib/active_record/associations/association.rb +31 -9
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +15 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +8 -2
- data/lib/active_record/associations/builder/belongs_to.rb +19 -6
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- 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 +2 -2
- data/lib/active_record/associations/collection_association.rb +14 -23
- data/lib/active_record/associations/collection_proxy.rb +8 -3
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +10 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/preloader/association.rb +161 -47
- data/lib/active_record/associations/preloader/batch.rb +51 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +37 -11
- data/lib/active_record/associations/preloader.rb +46 -110
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +76 -81
- data/lib/active_record/asynchronous_queries_tracker.rb +57 -0
- data/lib/active_record/attribute_assignment.rb +1 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +41 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +7 -5
- data/lib/active_record/attribute_methods/serialization.rb +66 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +6 -9
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +3 -18
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +2 -14
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +312 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +31 -558
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +45 -21
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +12 -14
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +60 -16
- data/lib/active_record/connection_adapters/abstract/transaction.rb +3 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +112 -66
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +96 -81
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +33 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +1 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -14
- 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 +1 -1
- 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 +28 -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 +6 -32
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +12 -12
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +159 -102
- data/lib/active_record/connection_adapters/schema_cache.rb +36 -37
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +23 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +20 -38
- data/lib/active_record/core.rb +111 -125
- data/lib/active_record/database_configurations/connection_url_resolver.rb +0 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -0
- data/lib/active_record/database_configurations/hash_config.rb +27 -1
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +17 -9
- data/lib/active_record/delegated_type.rb +33 -11
- data/lib/active_record/destroy_association_async_job.rb +1 -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/cipher/aes256_gcm.rb +98 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +44 -0
- data/lib/active_record/encryption/configurable.rb +61 -0
- data/lib/active_record/encryption/context.rb +35 -0
- data/lib/active_record/encryption/contexts.rb +72 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +208 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -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 +160 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +29 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +42 -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 +80 -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 +99 -0
- data/lib/active_record/encryption.rb +55 -0
- data/lib/active_record/enum.rb +41 -41
- data/lib/active_record/errors.rb +66 -3
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +40 -5
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +16 -11
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +55 -17
- data/lib/active_record/insert_all.rb +34 -5
- data/lib/active_record/integration.rb +1 -1
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/locking/optimistic.rb +10 -9
- data/lib/active_record/log_subscriber.rb +6 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +8 -3
- data/lib/active_record/migration/command_recorder.rb +4 -4
- data/lib/active_record/migration/compatibility.rb +89 -10
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +109 -79
- data/lib/active_record/model_schema.rb +45 -31
- data/lib/active_record/nested_attributes.rb +3 -3
- data/lib/active_record/no_touching.rb +2 -2
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +134 -45
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +203 -0
- data/lib/active_record/querying.rb +15 -5
- data/lib/active_record/railtie.rb +117 -17
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +72 -48
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +45 -44
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +39 -26
- data/lib/active_record/relation/delegation.rb +6 -6
- data/lib/active_record/relation/finder_methods.rb +31 -22
- data/lib/active_record/relation/merger.rb +20 -13
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +230 -49
- data/lib/active_record/relation/record_fetch_warning.rb +2 -2
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +8 -4
- data/lib/active_record/relation.rb +166 -77
- data/lib/active_record/result.rb +17 -2
- data/lib/active_record/runtime_registry.rb +2 -4
- data/lib/active_record/sanitization.rb +11 -7
- data/lib/active_record/schema_dumper.rb +3 -3
- data/lib/active_record/schema_migration.rb +0 -4
- data/lib/active_record/scoping/default.rb +61 -12
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +40 -22
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/store.rb +1 -6
- data/lib/active_record/tasks/database_tasks.rb +106 -22
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -11
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +9 -13
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +2 -2
- data/lib/active_record/type/adapter_specific_registry.rb +32 -7
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +2 -2
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record.rb +170 -2
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +18 -22
- data/lib/arel/delete_manager.rb +2 -4
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +8 -13
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/update_statement.rb +3 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +0 -1
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +2 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +6 -1
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +43 -2
- data/lib/arel.rb +1 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- 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
- metadata +52 -14
data/lib/active_record/core.rb
CHANGED
@@ -17,20 +17,7 @@ module ActiveRecord
|
|
17
17
|
# Accepts a logger conforming to the interface of Log4r which is then
|
18
18
|
# passed on to any new database connections made and which can be
|
19
19
|
# retrieved on both a class and instance level by calling +logger+.
|
20
|
-
|
21
|
-
|
22
|
-
##
|
23
|
-
# :singleton-method:
|
24
|
-
#
|
25
|
-
# Specifies if the methods calling database queries should be logged below
|
26
|
-
# their relevant queries. Defaults to false.
|
27
|
-
mattr_accessor :verbose_query_logs, instance_writer: false, default: false
|
28
|
-
|
29
|
-
##
|
30
|
-
# :singleton-method:
|
31
|
-
#
|
32
|
-
# Specifies the names of the queues used by background jobs.
|
33
|
-
mattr_accessor :queues, instance_accessor: false, default: {}
|
20
|
+
class_attribute :logger, instance_writer: false
|
34
21
|
|
35
22
|
##
|
36
23
|
# :singleton-method:
|
@@ -72,80 +59,17 @@ module ActiveRecord
|
|
72
59
|
|
73
60
|
##
|
74
61
|
# :singleton-method:
|
75
|
-
#
|
76
|
-
#
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
# :singleton-method:
|
81
|
-
# Specifies the format to use when dumping the database schema with Rails'
|
82
|
-
# Rakefile. If :sql, the schema is dumped as (potentially database-
|
83
|
-
# specific) SQL statements. If :ruby, the schema is dumped as an
|
84
|
-
# ActiveRecord::Schema file which can be loaded into any database that
|
85
|
-
# supports migrations. Use :ruby if you want to have different database
|
86
|
-
# adapters for, e.g., your development and test environments.
|
87
|
-
mattr_accessor :schema_format, instance_writer: false, default: :ruby
|
88
|
-
|
89
|
-
##
|
90
|
-
# :singleton-method:
|
91
|
-
# Specifies if an error should be raised if the query has an order being
|
92
|
-
# ignored when doing batch queries. Useful in applications where the
|
93
|
-
# scope being ignored is error-worthy, rather than a warning.
|
94
|
-
mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
|
95
|
-
|
96
|
-
##
|
97
|
-
# :singleton-method:
|
98
|
-
# Specify whether or not to use timestamps for migration versions
|
99
|
-
mattr_accessor :timestamped_migrations, instance_writer: false, default: true
|
100
|
-
|
101
|
-
##
|
102
|
-
# :singleton-method:
|
103
|
-
# Specify whether schema dump should happen at the end of the
|
104
|
-
# db:migrate rails command. This is true by default, which is useful for the
|
105
|
-
# development environment. This should ideally be false in the production
|
106
|
-
# environment where dumping schema is rarely needed.
|
107
|
-
mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
|
108
|
-
|
109
|
-
##
|
110
|
-
# :singleton-method:
|
111
|
-
# Specifies which database schemas to dump when calling db:schema:dump.
|
112
|
-
# If the value is :schema_search_path (the default), any schemas listed in
|
113
|
-
# schema_search_path are dumped. Use :all to dump all schemas regardless
|
114
|
-
# of schema_search_path, or a string of comma separated schemas for a
|
115
|
-
# custom list.
|
116
|
-
mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
|
117
|
-
|
118
|
-
##
|
119
|
-
# :singleton-method:
|
120
|
-
# Specify a threshold for the size of query result sets. If the number of
|
121
|
-
# records in the set exceeds the threshold, a warning is logged. This can
|
122
|
-
# be used to identify queries which load thousands of records and
|
123
|
-
# potentially cause memory bloat.
|
124
|
-
mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
|
125
|
-
|
126
|
-
##
|
127
|
-
# :singleton-method:
|
128
|
-
# Show a warning when Rails couldn't parse your database.yml
|
129
|
-
# for multiple databases.
|
130
|
-
mattr_accessor :suppress_multiple_database_warning, instance_writer: false, default: false
|
131
|
-
|
132
|
-
mattr_accessor :maintain_test_schema, instance_accessor: false
|
62
|
+
# Force enumeration of all columns in SELECT statements.
|
63
|
+
# e.g. `SELECT first_name, last_name FROM ...` instead of `SELECT * FROM ...`
|
64
|
+
# This avoids +PreparedStatementCacheExpired+ errors when a column is added
|
65
|
+
# to the database while the app is running.
|
66
|
+
class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false
|
133
67
|
|
134
68
|
class_attribute :belongs_to_required_by_default, instance_accessor: false
|
135
69
|
|
136
|
-
##
|
137
|
-
# :singleton-method:
|
138
|
-
# Set the application to log or raise when an association violates strict loading.
|
139
|
-
# Defaults to :raise.
|
140
|
-
mattr_accessor :action_on_strict_loading_violation, instance_accessor: false, default: :raise
|
141
|
-
|
142
70
|
class_attribute :strict_loading_by_default, instance_accessor: false, default: false
|
143
71
|
|
144
|
-
|
145
|
-
|
146
|
-
mattr_accessor :reading_role, instance_accessor: false, default: :reading
|
147
|
-
|
148
|
-
mattr_accessor :has_many_inversing, instance_accessor: false, default: false
|
72
|
+
class_attribute :has_many_inversing, instance_accessor: false, default: false
|
149
73
|
|
150
74
|
class_attribute :default_connection_handler, instance_writer: false
|
151
75
|
|
@@ -153,22 +77,15 @@ module ActiveRecord
|
|
153
77
|
|
154
78
|
class_attribute :default_shard, instance_writer: false
|
155
79
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
##
|
167
|
-
# :singleton-method:
|
168
|
-
# Application configurable boolean that denotes whether or not to raise
|
169
|
-
# an exception when the PostgreSQLAdapter is provided with an integer that is
|
170
|
-
# wider than signed 64bit representation
|
171
|
-
mattr_accessor :raise_int_wider_than_64bit, instance_writer: false, default: true
|
80
|
+
def self.application_record_class? # :nodoc:
|
81
|
+
if ActiveRecord.application_record_class
|
82
|
+
self == ActiveRecord.application_record_class
|
83
|
+
else
|
84
|
+
if defined?(ApplicationRecord) && self == ApplicationRecord
|
85
|
+
true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
172
89
|
|
173
90
|
self.filter_attributes = []
|
174
91
|
|
@@ -181,7 +98,8 @@ module ActiveRecord
|
|
181
98
|
end
|
182
99
|
|
183
100
|
def self.connection_handlers
|
184
|
-
|
101
|
+
if ActiveRecord.legacy_connection_handling
|
102
|
+
else
|
185
103
|
raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
|
186
104
|
end
|
187
105
|
|
@@ -189,13 +107,32 @@ module ActiveRecord
|
|
189
107
|
end
|
190
108
|
|
191
109
|
def self.connection_handlers=(handlers)
|
192
|
-
|
193
|
-
|
110
|
+
if ActiveRecord.legacy_connection_handling
|
111
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
112
|
+
Using legacy connection handling is deprecated. Please set
|
113
|
+
`legacy_connection_handling` to `false` in your application.
|
114
|
+
|
115
|
+
The new connection handling does not support `connection_handlers`
|
116
|
+
getter and setter.
|
117
|
+
|
118
|
+
Read more about how to migrate at: https://guides.rubyonrails.org/active_record_multiple_databases.html#migrate-to-the-new-connection-handling
|
119
|
+
MSG
|
120
|
+
else
|
121
|
+
raise NotImplementedError, "The new connection handling does not support multiple connection handlers."
|
194
122
|
end
|
195
123
|
|
196
124
|
@@connection_handlers = handlers
|
197
125
|
end
|
198
126
|
|
127
|
+
def self.asynchronous_queries_session # :nodoc:
|
128
|
+
asynchronous_queries_tracker.current_session
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.asynchronous_queries_tracker # :nodoc:
|
132
|
+
Thread.current.thread_variable_get(:ar_asynchronous_queries_tracker) ||
|
133
|
+
Thread.current.thread_variable_set(:ar_asynchronous_queries_tracker, AsynchronousQueriesTracker.new)
|
134
|
+
end
|
135
|
+
|
199
136
|
# Returns the symbol representing the current connected role.
|
200
137
|
#
|
201
138
|
# ActiveRecord::Base.connected_to(role: :writing) do
|
@@ -206,7 +143,7 @@ module ActiveRecord
|
|
206
143
|
# ActiveRecord::Base.current_role #=> :reading
|
207
144
|
# end
|
208
145
|
def self.current_role
|
209
|
-
if ActiveRecord
|
146
|
+
if ActiveRecord.legacy_connection_handling
|
210
147
|
connection_handlers.key(connection_handler) || default_role
|
211
148
|
else
|
212
149
|
connected_to_stack.reverse_each do |hash|
|
@@ -247,7 +184,7 @@ module ActiveRecord
|
|
247
184
|
# ActiveRecord::Base.current_preventing_writes #=> false
|
248
185
|
# end
|
249
186
|
def self.current_preventing_writes
|
250
|
-
if legacy_connection_handling
|
187
|
+
if ActiveRecord.legacy_connection_handling
|
251
188
|
connection_handler.prevent_writes
|
252
189
|
else
|
253
190
|
connected_to_stack.reverse_each do |hash|
|
@@ -273,7 +210,7 @@ module ActiveRecord
|
|
273
210
|
@connection_class = b
|
274
211
|
end
|
275
212
|
|
276
|
-
def self.connection_class # :nodoc
|
213
|
+
def self.connection_class # :nodoc:
|
277
214
|
@connection_class ||= false
|
278
215
|
end
|
279
216
|
|
@@ -301,11 +238,11 @@ module ActiveRecord
|
|
301
238
|
end
|
302
239
|
|
303
240
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
304
|
-
self.default_role = writing_role
|
241
|
+
self.default_role = ActiveRecord.writing_role
|
305
242
|
self.default_shard = :default
|
306
243
|
|
307
244
|
def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
|
308
|
-
case action_on_strict_loading_violation
|
245
|
+
case ActiveRecord.action_on_strict_loading_violation
|
309
246
|
when :raise
|
310
247
|
message = "`#{owner}` is marked for strict_loading. The `#{reflection.klass}` association named `:#{reflection.name}` cannot be lazily loaded."
|
311
248
|
raise ActiveRecord::StrictLoadingViolationError.new(message)
|
@@ -396,7 +333,32 @@ module ActiveRecord
|
|
396
333
|
end
|
397
334
|
|
398
335
|
def find_by!(*args) # :nodoc:
|
399
|
-
find_by(*args) ||
|
336
|
+
find_by(*args) || where(*args).raise_record_not_found_exception!
|
337
|
+
end
|
338
|
+
|
339
|
+
%w(
|
340
|
+
reading_role writing_role legacy_connection_handling default_timezone index_nested_attribute_errors
|
341
|
+
verbose_query_logs queues warn_on_records_fetched_greater_than maintain_test_schema
|
342
|
+
application_record_class action_on_strict_loading_violation schema_format error_on_ignored_order
|
343
|
+
timestamped_migrations dump_schema_after_migration dump_schemas suppress_multiple_database_warning
|
344
|
+
).each do |attr|
|
345
|
+
module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
346
|
+
def #{attr}
|
347
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
348
|
+
ActiveRecord::Base.#{attr} is deprecated and will be removed in Rails 7.1.
|
349
|
+
Use `ActiveRecord.#{attr}` instead.
|
350
|
+
MSG
|
351
|
+
ActiveRecord.#{attr}
|
352
|
+
end
|
353
|
+
|
354
|
+
def #{attr}=(value)
|
355
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
356
|
+
ActiveRecord::Base.#{attr}= is deprecated and will be removed in Rails 7.1.
|
357
|
+
Use `ActiveRecord.#{attr}=` instead.
|
358
|
+
MSG
|
359
|
+
ActiveRecord.#{attr} = value
|
360
|
+
end
|
361
|
+
RUBY
|
400
362
|
end
|
401
363
|
|
402
364
|
def initialize_generated_modules # :nodoc:
|
@@ -461,10 +423,6 @@ module ActiveRecord
|
|
461
423
|
end
|
462
424
|
|
463
425
|
# Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
|
464
|
-
#
|
465
|
-
# class Post < ActiveRecord::Base
|
466
|
-
# scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
|
467
|
-
# end
|
468
426
|
def arel_table # :nodoc:
|
469
427
|
@arel_table ||= Arel::Table.new(table_name, klass: self)
|
470
428
|
end
|
@@ -482,10 +440,6 @@ module ActiveRecord
|
|
482
440
|
TypeCaster::Map.new(self)
|
483
441
|
end
|
484
442
|
|
485
|
-
def _internal? # :nodoc:
|
486
|
-
false
|
487
|
-
end
|
488
|
-
|
489
443
|
def cached_find_by_statement(key, &block) # :nodoc:
|
490
444
|
cache = @find_by_statement_cache[connection.prepared_statements]
|
491
445
|
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
@@ -645,6 +599,8 @@ module ActiveRecord
|
|
645
599
|
# Delegates to id in order to allow two records of the same type and id to work with something like:
|
646
600
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
647
601
|
def hash
|
602
|
+
id = self.id
|
603
|
+
|
648
604
|
if id
|
649
605
|
self.class.hash ^ id.hash
|
650
606
|
else
|
@@ -696,11 +652,37 @@ module ActiveRecord
|
|
696
652
|
# if the record tries to lazily load an association.
|
697
653
|
#
|
698
654
|
# user = User.first
|
699
|
-
# user.strict_loading!
|
700
|
-
# user.comments
|
655
|
+
# user.strict_loading! # => true
|
656
|
+
# user.comments
|
701
657
|
# => ActiveRecord::StrictLoadingViolationError
|
702
|
-
|
703
|
-
|
658
|
+
#
|
659
|
+
# === Parameters:
|
660
|
+
#
|
661
|
+
# * value - Boolean specifying whether to enable or disable strict loading.
|
662
|
+
# * mode - Symbol specifying strict loading mode. Defaults to :all. Using
|
663
|
+
# :n_plus_one_only mode will only raise an error if an association
|
664
|
+
# that will lead to an n plus one query is lazily loaded.
|
665
|
+
#
|
666
|
+
# === Example:
|
667
|
+
#
|
668
|
+
# user = User.first
|
669
|
+
# user.strict_loading!(false) # => false
|
670
|
+
# user.comments
|
671
|
+
# => #<ActiveRecord::Associations::CollectionProxy>
|
672
|
+
def strict_loading!(value = true, mode: :all)
|
673
|
+
unless [:all, :n_plus_one_only].include?(mode)
|
674
|
+
raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only]."
|
675
|
+
end
|
676
|
+
|
677
|
+
@strict_loading_mode = mode
|
678
|
+
@strict_loading = value
|
679
|
+
end
|
680
|
+
|
681
|
+
attr_reader :strict_loading_mode
|
682
|
+
|
683
|
+
# Returns +true+ if the record uses strict_loading with +:n_plus_one_only+ mode enabled.
|
684
|
+
def strict_loading_n_plus_one_only?
|
685
|
+
@strict_loading_mode == :n_plus_one_only
|
704
686
|
end
|
705
687
|
|
706
688
|
# Marks this record as read only.
|
@@ -717,11 +699,11 @@ module ActiveRecord
|
|
717
699
|
# We check defined?(@attributes) not to issue warnings if the object is
|
718
700
|
# allocated but not initialized.
|
719
701
|
inspection = if defined?(@attributes) && @attributes
|
720
|
-
self.class.attribute_names.
|
702
|
+
self.class.attribute_names.filter_map do |name|
|
721
703
|
if _has_attribute?(name)
|
722
704
|
"#{name}: #{attribute_for_inspect(name)}"
|
723
705
|
end
|
724
|
-
end.
|
706
|
+
end.join(", ")
|
725
707
|
else
|
726
708
|
"not initialized"
|
727
709
|
end
|
@@ -778,16 +760,20 @@ module ActiveRecord
|
|
778
760
|
end
|
779
761
|
|
780
762
|
def init_internals
|
781
|
-
@primary_key = self.class.primary_key
|
782
763
|
@readonly = false
|
783
764
|
@previously_new_record = false
|
784
765
|
@destroyed = false
|
785
766
|
@marked_for_destruction = false
|
786
767
|
@destroyed_by_association = nil
|
787
768
|
@_start_transaction_state = nil
|
788
|
-
@strict_loading = self.class.strict_loading_by_default
|
789
769
|
|
790
|
-
self.class
|
770
|
+
klass = self.class
|
771
|
+
|
772
|
+
@primary_key = klass.primary_key
|
773
|
+
@strict_loading = klass.strict_loading_by_default
|
774
|
+
@strict_loading_mode = :all
|
775
|
+
|
776
|
+
klass.define_attribute_methods
|
791
777
|
end
|
792
778
|
|
793
779
|
def initialize_internals_callback
|
@@ -48,6 +48,18 @@ module ActiveRecord
|
|
48
48
|
raise NotImplementedError
|
49
49
|
end
|
50
50
|
|
51
|
+
def min_threads
|
52
|
+
raise NotImplementedError
|
53
|
+
end
|
54
|
+
|
55
|
+
def max_threads
|
56
|
+
raise NotImplementedError
|
57
|
+
end
|
58
|
+
|
59
|
+
def max_queue
|
60
|
+
raise NotImplementedError
|
61
|
+
end
|
62
|
+
|
51
63
|
def checkout_timeout
|
52
64
|
raise NotImplementedError
|
53
65
|
end
|
@@ -26,13 +26,14 @@ module ActiveRecord
|
|
26
26
|
# connections.
|
27
27
|
class HashConfig < DatabaseConfig
|
28
28
|
attr_reader :configuration_hash
|
29
|
+
|
29
30
|
def initialize(env_name, name, configuration_hash)
|
30
31
|
super(env_name, name)
|
31
32
|
@configuration_hash = configuration_hash.symbolize_keys.freeze
|
32
33
|
end
|
33
34
|
|
34
35
|
def config
|
35
|
-
ActiveSupport::Deprecation.warn("DatabaseConfig#config will be removed in 7.0.0 in favor of
|
36
|
+
ActiveSupport::Deprecation.warn("DatabaseConfig#config will be removed in 7.0.0 in favor of DatabaseConfigurations#configuration_hash which returns a hash with symbol keys")
|
36
37
|
configuration_hash.stringify_keys
|
37
38
|
end
|
38
39
|
|
@@ -54,6 +55,10 @@ module ActiveRecord
|
|
54
55
|
configuration_hash[:host]
|
55
56
|
end
|
56
57
|
|
58
|
+
def socket # :nodoc:
|
59
|
+
configuration_hash[:socket]
|
60
|
+
end
|
61
|
+
|
57
62
|
def database
|
58
63
|
configuration_hash[:database]
|
59
64
|
end
|
@@ -66,6 +71,18 @@ module ActiveRecord
|
|
66
71
|
(configuration_hash[:pool] || 5).to_i
|
67
72
|
end
|
68
73
|
|
74
|
+
def min_threads
|
75
|
+
(configuration_hash[:min_threads] || 0).to_i
|
76
|
+
end
|
77
|
+
|
78
|
+
def max_threads
|
79
|
+
(configuration_hash[:max_threads] || pool).to_i
|
80
|
+
end
|
81
|
+
|
82
|
+
def max_queue
|
83
|
+
max_threads * 4
|
84
|
+
end
|
85
|
+
|
69
86
|
def checkout_timeout
|
70
87
|
(configuration_hash[:checkout_timeout] || 5).to_f
|
71
88
|
end
|
@@ -91,6 +108,15 @@ module ActiveRecord
|
|
91
108
|
def schema_cache_path
|
92
109
|
configuration_hash[:schema_cache_path]
|
93
110
|
end
|
111
|
+
|
112
|
+
# Determines whether to dump the schema for a database.
|
113
|
+
def schema_dump
|
114
|
+
configuration_hash.fetch(:schema_dump, true)
|
115
|
+
end
|
116
|
+
|
117
|
+
def database_tasks? # :nodoc:
|
118
|
+
!replica? && !!configuration_hash.fetch(:database_tasks, true)
|
119
|
+
end
|
94
120
|
end
|
95
121
|
end
|
96
122
|
end
|
@@ -19,7 +19,7 @@ module ActiveRecord
|
|
19
19
|
#
|
20
20
|
# ==== Options
|
21
21
|
#
|
22
|
-
# * <tt>:env_name</tt> - The Rails environment,
|
22
|
+
# * <tt>:env_name</tt> - The Rails environment, i.e. "development".
|
23
23
|
# * <tt>:name</tt> - The db config name. In a standard two-tier
|
24
24
|
# database configuration this will default to "primary". In a multiple
|
25
25
|
# database three-tier database configuration this corresponds to the name
|
@@ -42,7 +42,7 @@ module ActiveRecord
|
|
42
42
|
# Return a Hash that can be merged into the main config that represents
|
43
43
|
# the passed in url
|
44
44
|
def build_url_hash
|
45
|
-
if url.nil? ||
|
45
|
+
if url.nil? || url.start_with?("jdbc:", "http:", "https:")
|
46
46
|
{ url: url }
|
47
47
|
else
|
48
48
|
ConnectionUrlResolver.new(url).to_hash
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "uri"
|
4
3
|
require "active_record/database_configurations/database_config"
|
5
4
|
require "active_record/database_configurations/hash_config"
|
6
5
|
require "active_record/database_configurations/url_config"
|
@@ -21,7 +20,7 @@ module ActiveRecord
|
|
21
20
|
end
|
22
21
|
|
23
22
|
# Collects the configs for the environment and optionally the specification
|
24
|
-
# name passed in. To include replica configurations pass <tt>
|
23
|
+
# name passed in. To include replica configurations pass <tt>include_hidden: true</tt>.
|
25
24
|
#
|
26
25
|
# If a name is provided a single DatabaseConfig object will be
|
27
26
|
# returned, otherwise an array of DatabaseConfig objects will be
|
@@ -34,22 +33,31 @@ module ActiveRecord
|
|
34
33
|
# * <tt>name:</tt> The db config name (i.e. primary, animals, etc.). Defaults
|
35
34
|
# to +nil+. If no +env_name+ is specified the config for the default env and the
|
36
35
|
# passed +name+ will be returned.
|
37
|
-
# * <tt>include_replicas:</tt> Determines whether to include replicas in
|
36
|
+
# * <tt>include_replicas:</tt> Deprecated. Determines whether to include replicas in
|
38
37
|
# the returned list. Most of the time we're only iterating over the write
|
39
38
|
# connection (i.e. migrations don't need to run for the write and read connection).
|
40
39
|
# Defaults to +false+.
|
41
|
-
|
40
|
+
# * <tt>include_hidden:</tte Determines whether to include replicas and configurations
|
41
|
+
# hidden by +database_tasks: false+ in the returned list. Most of the time we're only
|
42
|
+
# iterating over the primary connections (i.e. migrations don't need to run for the
|
43
|
+
# write and read connection). Defaults to +false+.
|
44
|
+
def configs_for(env_name: nil, spec_name: nil, name: nil, include_replicas: false, include_hidden: false)
|
42
45
|
if spec_name
|
43
46
|
name = spec_name
|
44
47
|
ActiveSupport::Deprecation.warn("The kwarg `spec_name` is deprecated in favor of `name`. `spec_name` will be removed in Rails 7.0")
|
45
48
|
end
|
46
49
|
|
50
|
+
if include_replicas
|
51
|
+
include_hidden = include_replicas
|
52
|
+
ActiveSupport::Deprecation.warn("The kwarg `include_replicas` is deprecated in favor of `include_hidden`. When `include_hidden` is passed, configurations with `replica: true` or `database_tasks: false` will be returned. `include_replicas` will be removed in Rails 7.1.")
|
53
|
+
end
|
54
|
+
|
47
55
|
env_name ||= default_env if name
|
48
56
|
configs = env_with_configs(env_name)
|
49
57
|
|
50
|
-
unless
|
58
|
+
unless include_hidden
|
51
59
|
configs = configs.select do |db_config|
|
52
|
-
|
60
|
+
db_config.database_tasks?
|
53
61
|
end
|
54
62
|
end
|
55
63
|
|
@@ -167,7 +175,7 @@ module ActiveRecord
|
|
167
175
|
return configs if configs.is_a?(Array)
|
168
176
|
|
169
177
|
db_configs = configs.flat_map do |env_name, config|
|
170
|
-
if config.is_a?(Hash) && config.all?
|
178
|
+
if config.is_a?(Hash) && config.values.all?(Hash)
|
171
179
|
walk_configs(env_name.to_s, config)
|
172
180
|
else
|
173
181
|
build_db_config_from_raw_config(env_name.to_s, "primary", config)
|
@@ -194,7 +202,7 @@ module ActiveRecord
|
|
194
202
|
raise AdapterNotSpecified, <<~MSG
|
195
203
|
The `#{name}` database is not configured for the `#{default_env}` environment.
|
196
204
|
|
197
|
-
Available
|
205
|
+
Available database configurations are:
|
198
206
|
|
199
207
|
#{build_configuration_sentence}
|
200
208
|
MSG
|
@@ -202,7 +210,7 @@ module ActiveRecord
|
|
202
210
|
end
|
203
211
|
|
204
212
|
def build_configuration_sentence
|
205
|
-
configs = configs_for(
|
213
|
+
configs = configs_for(include_hidden: true)
|
206
214
|
|
207
215
|
configs.group_by(&:env_name).map do |env, config|
|
208
216
|
names = config.map(&:name)
|
@@ -51,10 +51,9 @@ module ActiveRecord
|
|
51
51
|
# end
|
52
52
|
# end
|
53
53
|
#
|
54
|
-
# # Schema: messages[ id, subject ]
|
54
|
+
# # Schema: messages[ id, subject, body ]
|
55
55
|
# class Message < ApplicationRecord
|
56
56
|
# include Entryable
|
57
|
-
# has_rich_text :content
|
58
57
|
# end
|
59
58
|
#
|
60
59
|
# # Schema: comments[ id, content ]
|
@@ -66,7 +65,7 @@ module ActiveRecord
|
|
66
65
|
# resides in the +Entry+ "superclass". But the +Entry+ absolutely can stand alone in terms of querying capacity
|
67
66
|
# in particular. You can now easily do things like:
|
68
67
|
#
|
69
|
-
# Account.entries.order(created_at: :desc).limit(50)
|
68
|
+
# Account.find(1).entries.order(created_at: :desc).limit(50)
|
70
69
|
#
|
71
70
|
# Which is exactly what you want when displaying both comments and messages together. The entry itself can
|
72
71
|
# be rendered as its delegated type easily, like so:
|
@@ -76,7 +75,9 @@ module ActiveRecord
|
|
76
75
|
#
|
77
76
|
# # entries/entryables/_message.html.erb
|
78
77
|
# <div class="message">
|
79
|
-
#
|
78
|
+
# <div class="subject"><%= entry.message.subject %></div>
|
79
|
+
# <p><%= entry.message.body %></p>
|
80
|
+
# <i>Posted on <%= entry.created_at %> by <%= entry.creator.name %></i>
|
80
81
|
# </div>
|
81
82
|
#
|
82
83
|
# # entries/entryables/_comment.html.erb
|
@@ -156,8 +157,6 @@ module ActiveRecord
|
|
156
157
|
# Entry#comment # => returns the comment record, when entryable_type == "Comment", otherwise nil
|
157
158
|
# Entry#comment_id # => returns entryable_id, when entryable_type == "Comment", otherwise nil
|
158
159
|
#
|
159
|
-
# The +options+ are passed directly to the +belongs_to+ call, so this is where you declare +dependent+ etc.
|
160
|
-
#
|
161
160
|
# You can also declare namespaced types:
|
162
161
|
#
|
163
162
|
# class Entry < ApplicationRecord
|
@@ -167,15 +166,38 @@ module ActiveRecord
|
|
167
166
|
# Entry.access_notice_messages
|
168
167
|
# entry.access_notice_message
|
169
168
|
# entry.access_notice_message?
|
169
|
+
#
|
170
|
+
# === Options
|
171
|
+
#
|
172
|
+
# The +options+ are passed directly to the +belongs_to+ call, so this is where you declare +dependent+ etc.
|
173
|
+
# The following options can be included to specialize the behavior of the delegated type convenience methods.
|
174
|
+
#
|
175
|
+
# [:foreign_key]
|
176
|
+
# Specify the foreign key used for the convenience methods. By default this is guessed to be the passed
|
177
|
+
# +role+ with an "_id" suffix. So a class that defines a
|
178
|
+
# <tt>delegated_type :entryable, types: %w[ Message Comment ]</tt> association will use "entryable_id" as
|
179
|
+
# the default <tt>:foreign_key</tt>.
|
180
|
+
# [:primary_key]
|
181
|
+
# Specify the method that returns the primary key of associated object used for the convenience methods.
|
182
|
+
# By default this is +id+.
|
183
|
+
#
|
184
|
+
# Option examples:
|
185
|
+
# class Entry < ApplicationRecord
|
186
|
+
# delegated_type :entryable, types: %w[ Message Comment ], primary_key: :uuid, foreign_key: :entryable_uuid
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# Entry#message_uuid # => returns entryable_uuid, when entryable_type == "Message", otherwise nil
|
190
|
+
# Entry#comment_uuid # => returns entryable_uuid, when entryable_type == "Comment", otherwise nil
|
170
191
|
def delegated_type(role, types:, **options)
|
171
192
|
belongs_to role, options.delete(:scope), **options.merge(polymorphic: true)
|
172
|
-
define_delegated_type_methods role, types: types
|
193
|
+
define_delegated_type_methods role, types: types, options: options
|
173
194
|
end
|
174
195
|
|
175
196
|
private
|
176
|
-
def define_delegated_type_methods(role, types:)
|
197
|
+
def define_delegated_type_methods(role, types:, options:)
|
198
|
+
primary_key = options[:primary_key] || "id"
|
177
199
|
role_type = "#{role}_type"
|
178
|
-
role_id = "#{role}_id"
|
200
|
+
role_id = options[:foreign_key] || "#{role}_id"
|
179
201
|
|
180
202
|
define_method "#{role}_class" do
|
181
203
|
public_send("#{role}_type").constantize
|
@@ -186,7 +208,7 @@ module ActiveRecord
|
|
186
208
|
end
|
187
209
|
|
188
210
|
types.each do |type|
|
189
|
-
scope_name = type.tableize.
|
211
|
+
scope_name = type.tableize.tr("/", "_")
|
190
212
|
singular = scope_name.singularize
|
191
213
|
query = "#{singular}?"
|
192
214
|
|
@@ -200,7 +222,7 @@ module ActiveRecord
|
|
200
222
|
public_send(role) if public_send(query)
|
201
223
|
end
|
202
224
|
|
203
|
-
define_method "#{singular}
|
225
|
+
define_method "#{singular}_#{primary_key}" do
|
204
226
|
public_send(role_id) if public_send(query)
|
205
227
|
end
|
206
228
|
end
|
@@ -6,7 +6,7 @@ module ActiveRecord
|
|
6
6
|
|
7
7
|
# Job to destroy the records associated with a destroyed record in background.
|
8
8
|
class DestroyAssociationAsyncJob < ActiveJob::Base
|
9
|
-
queue_as { ActiveRecord
|
9
|
+
queue_as { ActiveRecord.queues[:destroy] }
|
10
10
|
|
11
11
|
discard_on ActiveJob::DeserializationError
|
12
12
|
|