activerecord 6.1.6 → 7.0.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1314 -975
- 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 +33 -17
- 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 +10 -3
- 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 +19 -21
- data/lib/active_record/associations/collection_proxy.rb +10 -5
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +8 -5
- 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/join_dependency.rb +23 -15
- data/lib/active_record/associations/preloader/association.rb +186 -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 +49 -13
- data/lib/active_record/associations/preloader.rb +39 -113
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +124 -95
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -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 +49 -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 +57 -19
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +8 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +14 -15
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +8 -23
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +10 -2
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -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 +47 -561
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +38 -13
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +80 -24
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
- data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +105 -81
- data/lib/active_record/connection_adapters/column.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -24
- data/lib/active_record/connection_adapters/mysql/quoting.rb +37 -21
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -12
- 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 +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 +51 -51
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +37 -19
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +208 -107
- data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +28 -16
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +17 -15
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +96 -32
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +49 -55
- data/lib/active_record/core.rb +124 -134
- data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -9
- data/lib/active_record/database_configurations/hash_config.rb +63 -5
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +15 -32
- data/lib/active_record/delegated_type.rb +53 -12
- 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 +67 -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 +206 -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 +28 -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 +90 -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 +50 -43
- data/lib/active_record/errors.rb +67 -4
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +41 -6
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +20 -23
- 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 +80 -14
- data/lib/active_record/integration.rb +4 -3
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +10 -9
- data/lib/active_record/locking/pessimistic.rb +10 -4
- data/lib/active_record/log_subscriber.rb +23 -7
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +18 -6
- data/lib/active_record/middleware/shard_selector.rb +60 -0
- data/lib/active_record/migration/command_recorder.rb +7 -7
- data/lib/active_record/migration/compatibility.rb +84 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +114 -83
- data/lib/active_record/model_schema.rb +58 -59
- data/lib/active_record/nested_attributes.rb +13 -12
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +228 -60
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +138 -0
- data/lib/active_record/querying.rb +16 -6
- data/lib/active_record/railtie.rb +136 -22
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +78 -136
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +73 -50
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +6 -6
- data/lib/active_record/relation/calculations.rb +43 -38
- data/lib/active_record/relation/delegation.rb +7 -7
- data/lib/active_record/relation/finder_methods.rb +31 -35
- 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 +276 -67
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +189 -88
- data/lib/active_record/result.rb +17 -7
- data/lib/active_record/runtime_registry.rb +9 -13
- data/lib/active_record/sanitization.rb +17 -12
- data/lib/active_record/schema.rb +38 -23
- data/lib/active_record/schema_dumper.rb +25 -19
- data/lib/active_record/schema_migration.rb +4 -4
- data/lib/active_record/scoping/default.rb +60 -13
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +64 -34
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +3 -3
- data/lib/active_record/store.rb +7 -2
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/tasks/database_tasks.rb +127 -60
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -13
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +16 -9
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +3 -3
- 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 +4 -4
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +4 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +217 -27
- 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/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/function.rb +1 -0
- 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 +8 -3
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/predications.rb +11 -3
- 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 +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +8 -2
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +58 -2
- data/lib/arel.rb +2 -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
- 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 +55 -11
@@ -44,7 +44,7 @@ module ActiveRecord
|
|
44
44
|
#
|
45
45
|
# ActiveRecord::Base.establish_connection(:production)
|
46
46
|
#
|
47
|
-
# The exceptions AdapterNotSpecified, AdapterNotFound and +ArgumentError+
|
47
|
+
# The exceptions AdapterNotSpecified, AdapterNotFound, and +ArgumentError+
|
48
48
|
# may be returned on an error.
|
49
49
|
def establish_connection(config_or_env = nil)
|
50
50
|
config_or_env ||= DEFAULT_ENV.call.to_sym
|
@@ -108,7 +108,7 @@ module ActiveRecord
|
|
108
108
|
connections
|
109
109
|
end
|
110
110
|
|
111
|
-
# Connects to a role (
|
111
|
+
# Connects to a role (e.g. writing, reading, or a custom role) and/or
|
112
112
|
# shard for the duration of the block. At the end of the block the
|
113
113
|
# connection will be returned to the original role / shard.
|
114
114
|
#
|
@@ -134,10 +134,8 @@ module ActiveRecord
|
|
134
134
|
# ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one_replica) do
|
135
135
|
# Dog.first # finds first Dog record stored on the shard one replica
|
136
136
|
# end
|
137
|
-
|
138
|
-
|
139
|
-
def connected_to(database: nil, role: nil, shard: nil, prevent_writes: false, &blk)
|
140
|
-
if legacy_connection_handling
|
137
|
+
def connected_to(role: nil, shard: nil, prevent_writes: false, &blk)
|
138
|
+
if ActiveRecord.legacy_connection_handling
|
141
139
|
if self != Base
|
142
140
|
raise NotImplementedError, "`connected_to` can only be called on ActiveRecord::Base with legacy connection handling."
|
143
141
|
end
|
@@ -151,31 +149,11 @@ module ActiveRecord
|
|
151
149
|
end
|
152
150
|
end
|
153
151
|
|
154
|
-
|
155
|
-
raise ArgumentError, "`connected_to` cannot accept a `database` argument with any other arguments."
|
156
|
-
elsif database
|
157
|
-
ActiveSupport::Deprecation.warn("The database key in `connected_to` is deprecated. It will be removed in Rails 7.0.0 without replacement.")
|
158
|
-
|
159
|
-
if database.is_a?(Hash)
|
160
|
-
role, database = database.first
|
161
|
-
role = role.to_sym
|
162
|
-
end
|
163
|
-
|
164
|
-
db_config, owner_name = resolve_config_for_connection(database)
|
165
|
-
handler = lookup_connection_handler(role)
|
166
|
-
|
167
|
-
handler.establish_connection(db_config, owner_name: owner_name, role: role)
|
168
|
-
|
169
|
-
with_handler(role, &blk)
|
170
|
-
elsif role || shard
|
171
|
-
unless role
|
172
|
-
raise ArgumentError, "`connected_to` cannot accept a `shard` argument without a `role`."
|
173
|
-
end
|
174
|
-
|
175
|
-
with_role_and_shard(role, shard, prevent_writes, &blk)
|
176
|
-
else
|
152
|
+
unless role || shard
|
177
153
|
raise ArgumentError, "must provide a `shard` and/or `role`."
|
178
154
|
end
|
155
|
+
|
156
|
+
with_role_and_shard(role, shard, prevent_writes, &blk)
|
179
157
|
end
|
180
158
|
|
181
159
|
# Connects a role and/or shard to the provided connection names. Optionally +prevent_writes+
|
@@ -194,7 +172,7 @@ module ActiveRecord
|
|
194
172
|
def connected_to_many(*classes, role:, shard: nil, prevent_writes: false)
|
195
173
|
classes = classes.flatten
|
196
174
|
|
197
|
-
if legacy_connection_handling
|
175
|
+
if ActiveRecord.legacy_connection_handling
|
198
176
|
raise NotImplementedError, "connected_to_many is not available with legacy connection handling"
|
199
177
|
end
|
200
178
|
|
@@ -202,9 +180,9 @@ module ActiveRecord
|
|
202
180
|
raise NotImplementedError, "connected_to_many can only be called on ActiveRecord::Base."
|
203
181
|
end
|
204
182
|
|
205
|
-
prevent_writes = true if role == reading_role
|
183
|
+
prevent_writes = true if role == ActiveRecord.reading_role
|
206
184
|
|
207
|
-
|
185
|
+
append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: classes)
|
208
186
|
yield
|
209
187
|
ensure
|
210
188
|
connected_to_stack.pop
|
@@ -218,13 +196,32 @@ module ActiveRecord
|
|
218
196
|
# It is not recommended to use this method in a request since it
|
219
197
|
# does not yield to a block like +connected_to+.
|
220
198
|
def connecting_to(role: default_role, shard: default_shard, prevent_writes: false)
|
221
|
-
if legacy_connection_handling
|
199
|
+
if ActiveRecord.legacy_connection_handling
|
222
200
|
raise NotImplementedError, "`connecting_to` is not available with `legacy_connection_handling`."
|
223
201
|
end
|
224
202
|
|
225
|
-
prevent_writes = true if role == reading_role
|
203
|
+
prevent_writes = true if role == ActiveRecord.reading_role
|
226
204
|
|
227
|
-
|
205
|
+
append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: [self])
|
206
|
+
end
|
207
|
+
|
208
|
+
# Prohibit swapping shards while inside of the passed block.
|
209
|
+
#
|
210
|
+
# In some cases you may want to be able to swap shards but not allow a
|
211
|
+
# nested call to connected_to or connected_to_many to swap again. This
|
212
|
+
# is useful in cases you're using sharding to provide per-request
|
213
|
+
# database isolation.
|
214
|
+
def prohibit_shard_swapping(enabled = true)
|
215
|
+
prev_value = ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping]
|
216
|
+
ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] = enabled
|
217
|
+
yield
|
218
|
+
ensure
|
219
|
+
ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] = prev_value
|
220
|
+
end
|
221
|
+
|
222
|
+
# Determine whether or not shard swapping is currently prohibited
|
223
|
+
def shard_swapping_prohibited?
|
224
|
+
ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping]
|
228
225
|
end
|
229
226
|
|
230
227
|
# Prevent writing to the database regardless of role.
|
@@ -239,7 +236,7 @@ module ActiveRecord
|
|
239
236
|
# See +READ_QUERY+ for the queries that are blocked by this
|
240
237
|
# method.
|
241
238
|
def while_preventing_writes(enabled = true, &block)
|
242
|
-
if legacy_connection_handling
|
239
|
+
if ActiveRecord.legacy_connection_handling
|
243
240
|
connection_handler.while_preventing_writes(enabled, &block)
|
244
241
|
else
|
245
242
|
connected_to(role: current_role, prevent_writes: enabled, &block)
|
@@ -257,8 +254,8 @@ module ActiveRecord
|
|
257
254
|
end
|
258
255
|
|
259
256
|
def lookup_connection_handler(handler_key) # :nodoc:
|
260
|
-
if ActiveRecord
|
261
|
-
handler_key ||= ActiveRecord
|
257
|
+
if ActiveRecord.legacy_connection_handling
|
258
|
+
handler_key ||= ActiveRecord.writing_role
|
262
259
|
connection_handlers[handler_key] ||= ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
263
260
|
else
|
264
261
|
ActiveRecord::Base.connection_handler
|
@@ -267,7 +264,7 @@ module ActiveRecord
|
|
267
264
|
|
268
265
|
# Clears the query cache for all connections associated with the current thread.
|
269
266
|
def clear_query_caches_for_current_thread
|
270
|
-
if ActiveRecord
|
267
|
+
if ActiveRecord.legacy_connection_handling
|
271
268
|
ActiveRecord::Base.connection_handlers.each_value do |handler|
|
272
269
|
clear_on_handler(handler)
|
273
270
|
end
|
@@ -294,19 +291,8 @@ module ActiveRecord
|
|
294
291
|
end
|
295
292
|
|
296
293
|
def primary_class? # :nodoc:
|
297
|
-
self == Base ||
|
298
|
-
end
|
299
|
-
|
300
|
-
# Returns the configuration of the associated connection as a hash:
|
301
|
-
#
|
302
|
-
# ActiveRecord::Base.connection_config
|
303
|
-
# # => {pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"}
|
304
|
-
#
|
305
|
-
# Please use only for reading.
|
306
|
-
def connection_config
|
307
|
-
connection_pool.db_config.configuration_hash
|
294
|
+
self == Base || application_record_class?
|
308
295
|
end
|
309
|
-
deprecate connection_config: "Use connection_db_config instead"
|
310
296
|
|
311
297
|
# Returns the db_config object from the associated connection:
|
312
298
|
#
|
@@ -374,17 +360,17 @@ module ActiveRecord
|
|
374
360
|
end
|
375
361
|
|
376
362
|
def with_role_and_shard(role, shard, prevent_writes)
|
377
|
-
prevent_writes = true if role == reading_role
|
363
|
+
prevent_writes = true if role == ActiveRecord.reading_role
|
378
364
|
|
379
|
-
if ActiveRecord
|
365
|
+
if ActiveRecord.legacy_connection_handling
|
380
366
|
with_handler(role.to_sym) do
|
381
367
|
connection_handler.while_preventing_writes(prevent_writes) do
|
382
|
-
|
368
|
+
append_to_connected_to_stack(shard: shard, klasses: [self])
|
383
369
|
yield
|
384
370
|
end
|
385
371
|
end
|
386
372
|
else
|
387
|
-
|
373
|
+
append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: [self])
|
388
374
|
return_value = yield
|
389
375
|
return_value.load if return_value.is_a? ActiveRecord::Relation
|
390
376
|
return_value
|
@@ -393,6 +379,14 @@ module ActiveRecord
|
|
393
379
|
self.connected_to_stack.pop
|
394
380
|
end
|
395
381
|
|
382
|
+
def append_to_connected_to_stack(entry)
|
383
|
+
if shard_swapping_prohibited? && entry[:shard].present?
|
384
|
+
raise ArgumentError, "cannot swap `shard` while shard swapping is prohibited."
|
385
|
+
end
|
386
|
+
|
387
|
+
connected_to_stack << entry
|
388
|
+
end
|
389
|
+
|
396
390
|
def swap_connection_handler(handler, &blk) # :nodoc:
|
397
391
|
old_handler, ActiveRecord::Base.connection_handler = ActiveRecord::Base.connection_handler, handler
|
398
392
|
return_value = yield
|
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. <tt>SELECT first_name, last_name FROM ...</tt> instead of <tt>SELECT * FROM ...</tt>
|
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,20 +77,31 @@ module ActiveRecord
|
|
153
77
|
|
154
78
|
class_attribute :default_shard, instance_writer: false
|
155
79
|
|
156
|
-
|
80
|
+
class_attribute :shard_selector, instance_accessor: false, default: nil
|
81
|
+
|
82
|
+
def self.application_record_class? # :nodoc:
|
83
|
+
if ActiveRecord.application_record_class
|
84
|
+
self == ActiveRecord.application_record_class
|
85
|
+
else
|
86
|
+
if defined?(ApplicationRecord) && self == ApplicationRecord
|
87
|
+
true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
157
91
|
|
158
92
|
self.filter_attributes = []
|
159
93
|
|
160
94
|
def self.connection_handler
|
161
|
-
|
95
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
|
162
96
|
end
|
163
97
|
|
164
98
|
def self.connection_handler=(handler)
|
165
|
-
|
99
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
|
166
100
|
end
|
167
101
|
|
168
102
|
def self.connection_handlers
|
169
|
-
|
103
|
+
if ActiveRecord.legacy_connection_handling
|
104
|
+
else
|
170
105
|
raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
|
171
106
|
end
|
172
107
|
|
@@ -174,13 +109,32 @@ module ActiveRecord
|
|
174
109
|
end
|
175
110
|
|
176
111
|
def self.connection_handlers=(handlers)
|
177
|
-
|
178
|
-
|
112
|
+
if ActiveRecord.legacy_connection_handling
|
113
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
114
|
+
Using legacy connection handling is deprecated. Please set
|
115
|
+
`legacy_connection_handling` to `false` in your application.
|
116
|
+
|
117
|
+
The new connection handling does not support `connection_handlers`
|
118
|
+
getter and setter.
|
119
|
+
|
120
|
+
Read more about how to migrate at: https://guides.rubyonrails.org/active_record_multiple_databases.html#migrate-to-the-new-connection-handling
|
121
|
+
MSG
|
122
|
+
else
|
123
|
+
raise NotImplementedError, "The new connection handling does not support multiple connection handlers."
|
179
124
|
end
|
180
125
|
|
181
126
|
@@connection_handlers = handlers
|
182
127
|
end
|
183
128
|
|
129
|
+
def self.asynchronous_queries_session # :nodoc:
|
130
|
+
asynchronous_queries_tracker.current_session
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.asynchronous_queries_tracker # :nodoc:
|
134
|
+
ActiveSupport::IsolatedExecutionState[:active_record_asynchronous_queries_tracker] ||= \
|
135
|
+
AsynchronousQueriesTracker.new
|
136
|
+
end
|
137
|
+
|
184
138
|
# Returns the symbol representing the current connected role.
|
185
139
|
#
|
186
140
|
# ActiveRecord::Base.connected_to(role: :writing) do
|
@@ -191,12 +145,12 @@ module ActiveRecord
|
|
191
145
|
# ActiveRecord::Base.current_role #=> :reading
|
192
146
|
# end
|
193
147
|
def self.current_role
|
194
|
-
if ActiveRecord
|
148
|
+
if ActiveRecord.legacy_connection_handling
|
195
149
|
connection_handlers.key(connection_handler) || default_role
|
196
150
|
else
|
197
151
|
connected_to_stack.reverse_each do |hash|
|
198
152
|
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
199
|
-
return hash[:role] if hash[:role] && hash[:klasses].include?(
|
153
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
|
200
154
|
end
|
201
155
|
|
202
156
|
default_role
|
@@ -215,7 +169,7 @@ module ActiveRecord
|
|
215
169
|
def self.current_shard
|
216
170
|
connected_to_stack.reverse_each do |hash|
|
217
171
|
return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
|
218
|
-
return hash[:shard] if hash[:shard] && hash[:klasses].include?(
|
172
|
+
return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
|
219
173
|
end
|
220
174
|
|
221
175
|
default_shard
|
@@ -232,12 +186,12 @@ module ActiveRecord
|
|
232
186
|
# ActiveRecord::Base.current_preventing_writes #=> false
|
233
187
|
# end
|
234
188
|
def self.current_preventing_writes
|
235
|
-
if legacy_connection_handling
|
189
|
+
if ActiveRecord.legacy_connection_handling
|
236
190
|
connection_handler.prevent_writes
|
237
191
|
else
|
238
192
|
connected_to_stack.reverse_each do |hash|
|
239
193
|
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
|
240
|
-
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(
|
194
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
|
241
195
|
end
|
242
196
|
|
243
197
|
false
|
@@ -245,11 +199,11 @@ module ActiveRecord
|
|
245
199
|
end
|
246
200
|
|
247
201
|
def self.connected_to_stack # :nodoc:
|
248
|
-
if connected_to_stack =
|
202
|
+
if connected_to_stack = ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack]
|
249
203
|
connected_to_stack
|
250
204
|
else
|
251
205
|
connected_to_stack = Concurrent::Array.new
|
252
|
-
|
206
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack] = connected_to_stack
|
253
207
|
connected_to_stack
|
254
208
|
end
|
255
209
|
end
|
@@ -258,7 +212,7 @@ module ActiveRecord
|
|
258
212
|
@connection_class = b
|
259
213
|
end
|
260
214
|
|
261
|
-
def self.connection_class # :nodoc
|
215
|
+
def self.connection_class # :nodoc:
|
262
216
|
@connection_class ||= false
|
263
217
|
end
|
264
218
|
|
@@ -266,7 +220,7 @@ module ActiveRecord
|
|
266
220
|
self.connection_class
|
267
221
|
end
|
268
222
|
|
269
|
-
def self.
|
223
|
+
def self.connection_class_for_self # :nodoc:
|
270
224
|
klass = self
|
271
225
|
|
272
226
|
until klass == Base
|
@@ -277,22 +231,14 @@ module ActiveRecord
|
|
277
231
|
klass
|
278
232
|
end
|
279
233
|
|
280
|
-
def self.allow_unsafe_raw_sql # :nodoc:
|
281
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 7.0")
|
282
|
-
end
|
283
|
-
|
284
|
-
def self.allow_unsafe_raw_sql=(value) # :nodoc:
|
285
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 7.0")
|
286
|
-
end
|
287
|
-
|
288
234
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
289
|
-
self.default_role = writing_role
|
235
|
+
self.default_role = ActiveRecord.writing_role
|
290
236
|
self.default_shard = :default
|
291
237
|
|
292
238
|
def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
|
293
|
-
case action_on_strict_loading_violation
|
239
|
+
case ActiveRecord.action_on_strict_loading_violation
|
294
240
|
when :raise
|
295
|
-
message =
|
241
|
+
message = reflection.strict_loading_violation_message(owner)
|
296
242
|
raise ActiveRecord::StrictLoadingViolationError.new(message)
|
297
243
|
when :log
|
298
244
|
name = "strict_loading_violation.active_record"
|
@@ -381,7 +327,32 @@ module ActiveRecord
|
|
381
327
|
end
|
382
328
|
|
383
329
|
def find_by!(*args) # :nodoc:
|
384
|
-
find_by(*args) ||
|
330
|
+
find_by(*args) || where(*args).raise_record_not_found_exception!
|
331
|
+
end
|
332
|
+
|
333
|
+
%w(
|
334
|
+
reading_role writing_role legacy_connection_handling default_timezone index_nested_attribute_errors
|
335
|
+
verbose_query_logs queues warn_on_records_fetched_greater_than maintain_test_schema
|
336
|
+
application_record_class action_on_strict_loading_violation schema_format error_on_ignored_order
|
337
|
+
timestamped_migrations dump_schema_after_migration dump_schemas suppress_multiple_database_warning
|
338
|
+
).each do |attr|
|
339
|
+
module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
340
|
+
def #{attr}
|
341
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
342
|
+
ActiveRecord::Base.#{attr} is deprecated and will be removed in Rails 7.1.
|
343
|
+
Use `ActiveRecord.#{attr}` instead.
|
344
|
+
MSG
|
345
|
+
ActiveRecord.#{attr}
|
346
|
+
end
|
347
|
+
|
348
|
+
def #{attr}=(value)
|
349
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
350
|
+
ActiveRecord::Base.#{attr}= is deprecated and will be removed in Rails 7.1.
|
351
|
+
Use `ActiveRecord.#{attr}=` instead.
|
352
|
+
MSG
|
353
|
+
ActiveRecord.#{attr} = value
|
354
|
+
end
|
355
|
+
RUBY
|
385
356
|
end
|
386
357
|
|
387
358
|
def initialize_generated_modules # :nodoc:
|
@@ -440,25 +411,16 @@ module ActiveRecord
|
|
440
411
|
end
|
441
412
|
end
|
442
413
|
|
443
|
-
#
|
414
|
+
# Override the default class equality method to provide support for decorated models.
|
444
415
|
def ===(object) # :nodoc:
|
445
416
|
object.is_a?(self)
|
446
417
|
end
|
447
418
|
|
448
419
|
# Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
|
449
|
-
#
|
450
|
-
# class Post < ActiveRecord::Base
|
451
|
-
# scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
|
452
|
-
# end
|
453
420
|
def arel_table # :nodoc:
|
454
421
|
@arel_table ||= Arel::Table.new(table_name, klass: self)
|
455
422
|
end
|
456
423
|
|
457
|
-
def arel_attribute(name, table = arel_table) # :nodoc:
|
458
|
-
table[name]
|
459
|
-
end
|
460
|
-
deprecate :arel_attribute
|
461
|
-
|
462
424
|
def predicate_builder # :nodoc:
|
463
425
|
@predicate_builder ||= PredicateBuilder.new(table_metadata)
|
464
426
|
end
|
@@ -467,10 +429,6 @@ module ActiveRecord
|
|
467
429
|
TypeCaster::Map.new(self)
|
468
430
|
end
|
469
431
|
|
470
|
-
def _internal? # :nodoc:
|
471
|
-
false
|
472
|
-
end
|
473
|
-
|
474
432
|
def cached_find_by_statement(key, &block) # :nodoc:
|
475
433
|
cache = @find_by_statement_cache[connection.prepared_statements]
|
476
434
|
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
@@ -528,7 +486,7 @@ module ActiveRecord
|
|
528
486
|
# post.init_with(coder)
|
529
487
|
# post.title # => 'hello world'
|
530
488
|
def init_with(coder, &block)
|
531
|
-
coder = LegacyYamlAdapter.convert(
|
489
|
+
coder = LegacyYamlAdapter.convert(coder)
|
532
490
|
attributes = self.class.yaml_encoder.decode(coder)
|
533
491
|
init_with_attributes(attributes, coder["new_record"], &block)
|
534
492
|
end
|
@@ -630,6 +588,8 @@ module ActiveRecord
|
|
630
588
|
# Delegates to id in order to allow two records of the same type and id to work with something like:
|
631
589
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
632
590
|
def hash
|
591
|
+
id = self.id
|
592
|
+
|
633
593
|
if id
|
634
594
|
self.class.hash ^ id.hash
|
635
595
|
else
|
@@ -681,11 +641,37 @@ module ActiveRecord
|
|
681
641
|
# if the record tries to lazily load an association.
|
682
642
|
#
|
683
643
|
# user = User.first
|
684
|
-
# user.strict_loading!
|
685
|
-
# user.comments
|
644
|
+
# user.strict_loading! # => true
|
645
|
+
# user.comments
|
686
646
|
# => ActiveRecord::StrictLoadingViolationError
|
687
|
-
|
688
|
-
|
647
|
+
#
|
648
|
+
# === Parameters:
|
649
|
+
#
|
650
|
+
# * value - Boolean specifying whether to enable or disable strict loading.
|
651
|
+
# * mode - Symbol specifying strict loading mode. Defaults to :all. Using
|
652
|
+
# :n_plus_one_only mode will only raise an error if an association
|
653
|
+
# that will lead to an n plus one query is lazily loaded.
|
654
|
+
#
|
655
|
+
# === Example:
|
656
|
+
#
|
657
|
+
# user = User.first
|
658
|
+
# user.strict_loading!(false) # => false
|
659
|
+
# user.comments
|
660
|
+
# => #<ActiveRecord::Associations::CollectionProxy>
|
661
|
+
def strict_loading!(value = true, mode: :all)
|
662
|
+
unless [:all, :n_plus_one_only].include?(mode)
|
663
|
+
raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only]."
|
664
|
+
end
|
665
|
+
|
666
|
+
@strict_loading_mode = mode
|
667
|
+
@strict_loading = value
|
668
|
+
end
|
669
|
+
|
670
|
+
attr_reader :strict_loading_mode
|
671
|
+
|
672
|
+
# Returns +true+ if the record uses strict_loading with +:n_plus_one_only+ mode enabled.
|
673
|
+
def strict_loading_n_plus_one_only?
|
674
|
+
@strict_loading_mode == :n_plus_one_only
|
689
675
|
end
|
690
676
|
|
691
677
|
# Marks this record as read only.
|
@@ -702,11 +688,11 @@ module ActiveRecord
|
|
702
688
|
# We check defined?(@attributes) not to issue warnings if the object is
|
703
689
|
# allocated but not initialized.
|
704
690
|
inspection = if defined?(@attributes) && @attributes
|
705
|
-
self.class.attribute_names.
|
691
|
+
self.class.attribute_names.filter_map do |name|
|
706
692
|
if _has_attribute?(name)
|
707
693
|
"#{name}: #{attribute_for_inspect(name)}"
|
708
694
|
end
|
709
|
-
end.
|
695
|
+
end.join(", ")
|
710
696
|
else
|
711
697
|
"not initialized"
|
712
698
|
end
|
@@ -763,16 +749,20 @@ module ActiveRecord
|
|
763
749
|
end
|
764
750
|
|
765
751
|
def init_internals
|
766
|
-
@primary_key = self.class.primary_key
|
767
752
|
@readonly = false
|
768
753
|
@previously_new_record = false
|
769
754
|
@destroyed = false
|
770
755
|
@marked_for_destruction = false
|
771
756
|
@destroyed_by_association = nil
|
772
757
|
@_start_transaction_state = nil
|
773
|
-
@strict_loading = self.class.strict_loading_by_default
|
774
758
|
|
775
|
-
self.class
|
759
|
+
klass = self.class
|
760
|
+
|
761
|
+
@primary_key = klass.primary_key
|
762
|
+
@strict_loading = klass.strict_loading_by_default
|
763
|
+
@strict_loading_mode = :all
|
764
|
+
|
765
|
+
klass.define_attribute_methods
|
776
766
|
end
|
777
767
|
|
778
768
|
def initialize_internals_callback
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "uri"
|
4
4
|
require "active_support/core_ext/enumerable"
|
5
|
+
require "active_support/core_ext/hash/reverse_merge"
|
5
6
|
|
6
7
|
module ActiveRecord
|
7
8
|
class DatabaseConfigurations
|
@@ -68,7 +69,7 @@ module ActiveRecord
|
|
68
69
|
database: uri.opaque
|
69
70
|
)
|
70
71
|
else
|
71
|
-
query_hash.
|
72
|
+
query_hash.reverse_merge(
|
72
73
|
adapter: @adapter,
|
73
74
|
username: uri.user,
|
74
75
|
password: uri.password,
|