activerecord 6.1.7.4 → 7.0.6
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 +1449 -1014
- data/README.rdoc +3 -3
- 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 +14 -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 +50 -14
- data/lib/active_record/associations/preloader.rb +39 -113
- data/lib/active_record/associations/singular_association.rb +15 -7
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +138 -100
- 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 +8 -6
- data/lib/active_record/attribute_methods/serialization.rb +57 -19
- 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 +19 -22
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +17 -28
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +14 -16
- data/lib/active_record/coders/yaml_column.rb +4 -8
- 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 +52 -23
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +82 -25
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
- data/lib/active_record/connection_adapters/abstract_adapter.rb +153 -74
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +112 -84
- 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 +45 -21
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +4 -1
- 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 +19 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -17
- 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 +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 +71 -71
- 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 +40 -21
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -106
- 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 +97 -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 +123 -148
- 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/explain_subscriber.rb +1 -1
- 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 +5 -5
- 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 +36 -21
- 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 +8 -9
- data/lib/active_record/migration/compatibility.rb +91 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +115 -84
- 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 +149 -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 +80 -49
- 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 +92 -60
- 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/association_query_value.rb +20 -1
- data/lib/active_record/relation/predicate_builder.rb +2 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +285 -68
- 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 +23 -11
- 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 +29 -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 +2 -2
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/table_metadata.rb +5 -1
- 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 +9 -6
- 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 +5 -5
- 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 +225 -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 +58 -14
@@ -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,35 +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
|
157
81
|
|
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
|
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
|
172
91
|
|
173
92
|
self.filter_attributes = []
|
174
93
|
|
175
94
|
def self.connection_handler
|
176
|
-
|
95
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
|
177
96
|
end
|
178
97
|
|
179
98
|
def self.connection_handler=(handler)
|
180
|
-
|
99
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
|
181
100
|
end
|
182
101
|
|
183
102
|
def self.connection_handlers
|
184
|
-
|
103
|
+
if ActiveRecord.legacy_connection_handling
|
104
|
+
else
|
185
105
|
raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
|
186
106
|
end
|
187
107
|
|
@@ -189,13 +109,32 @@ module ActiveRecord
|
|
189
109
|
end
|
190
110
|
|
191
111
|
def self.connection_handlers=(handlers)
|
192
|
-
|
193
|
-
|
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."
|
194
124
|
end
|
195
125
|
|
196
126
|
@@connection_handlers = handlers
|
197
127
|
end
|
198
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
|
+
|
199
138
|
# Returns the symbol representing the current connected role.
|
200
139
|
#
|
201
140
|
# ActiveRecord::Base.connected_to(role: :writing) do
|
@@ -206,12 +145,12 @@ module ActiveRecord
|
|
206
145
|
# ActiveRecord::Base.current_role #=> :reading
|
207
146
|
# end
|
208
147
|
def self.current_role
|
209
|
-
if ActiveRecord
|
148
|
+
if ActiveRecord.legacy_connection_handling
|
210
149
|
connection_handlers.key(connection_handler) || default_role
|
211
150
|
else
|
212
151
|
connected_to_stack.reverse_each do |hash|
|
213
152
|
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
214
|
-
return hash[:role] if hash[:role] && hash[:klasses].include?(
|
153
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
|
215
154
|
end
|
216
155
|
|
217
156
|
default_role
|
@@ -230,7 +169,7 @@ module ActiveRecord
|
|
230
169
|
def self.current_shard
|
231
170
|
connected_to_stack.reverse_each do |hash|
|
232
171
|
return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
|
233
|
-
return hash[:shard] if hash[:shard] && hash[:klasses].include?(
|
172
|
+
return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
|
234
173
|
end
|
235
174
|
|
236
175
|
default_shard
|
@@ -247,12 +186,12 @@ module ActiveRecord
|
|
247
186
|
# ActiveRecord::Base.current_preventing_writes #=> false
|
248
187
|
# end
|
249
188
|
def self.current_preventing_writes
|
250
|
-
if legacy_connection_handling
|
189
|
+
if ActiveRecord.legacy_connection_handling
|
251
190
|
connection_handler.prevent_writes
|
252
191
|
else
|
253
192
|
connected_to_stack.reverse_each do |hash|
|
254
193
|
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
|
255
|
-
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)
|
256
195
|
end
|
257
196
|
|
258
197
|
false
|
@@ -260,11 +199,11 @@ module ActiveRecord
|
|
260
199
|
end
|
261
200
|
|
262
201
|
def self.connected_to_stack # :nodoc:
|
263
|
-
if connected_to_stack =
|
202
|
+
if connected_to_stack = ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack]
|
264
203
|
connected_to_stack
|
265
204
|
else
|
266
205
|
connected_to_stack = Concurrent::Array.new
|
267
|
-
|
206
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack] = connected_to_stack
|
268
207
|
connected_to_stack
|
269
208
|
end
|
270
209
|
end
|
@@ -273,7 +212,7 @@ module ActiveRecord
|
|
273
212
|
@connection_class = b
|
274
213
|
end
|
275
214
|
|
276
|
-
def self.connection_class # :nodoc
|
215
|
+
def self.connection_class # :nodoc:
|
277
216
|
@connection_class ||= false
|
278
217
|
end
|
279
218
|
|
@@ -281,7 +220,7 @@ module ActiveRecord
|
|
281
220
|
self.connection_class
|
282
221
|
end
|
283
222
|
|
284
|
-
def self.
|
223
|
+
def self.connection_class_for_self # :nodoc:
|
285
224
|
klass = self
|
286
225
|
|
287
226
|
until klass == Base
|
@@ -292,22 +231,14 @@ module ActiveRecord
|
|
292
231
|
klass
|
293
232
|
end
|
294
233
|
|
295
|
-
def self.allow_unsafe_raw_sql # :nodoc:
|
296
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 7.0")
|
297
|
-
end
|
298
|
-
|
299
|
-
def self.allow_unsafe_raw_sql=(value) # :nodoc:
|
300
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 7.0")
|
301
|
-
end
|
302
|
-
|
303
234
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
304
|
-
self.default_role = writing_role
|
235
|
+
self.default_role = ActiveRecord.writing_role
|
305
236
|
self.default_shard = :default
|
306
237
|
|
307
238
|
def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
|
308
|
-
case action_on_strict_loading_violation
|
239
|
+
case ActiveRecord.action_on_strict_loading_violation
|
309
240
|
when :raise
|
310
|
-
message =
|
241
|
+
message = reflection.strict_loading_violation_message(owner)
|
311
242
|
raise ActiveRecord::StrictLoadingViolationError.new(message)
|
312
243
|
when :log
|
313
244
|
name = "strict_loading_violation.active_record"
|
@@ -396,7 +327,32 @@ module ActiveRecord
|
|
396
327
|
end
|
397
328
|
|
398
329
|
def find_by!(*args) # :nodoc:
|
399
|
-
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
|
400
356
|
end
|
401
357
|
|
402
358
|
def initialize_generated_modules # :nodoc:
|
@@ -455,25 +411,16 @@ module ActiveRecord
|
|
455
411
|
end
|
456
412
|
end
|
457
413
|
|
458
|
-
#
|
414
|
+
# Override the default class equality method to provide support for decorated models.
|
459
415
|
def ===(object) # :nodoc:
|
460
416
|
object.is_a?(self)
|
461
417
|
end
|
462
418
|
|
463
419
|
# 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
420
|
def arel_table # :nodoc:
|
469
421
|
@arel_table ||= Arel::Table.new(table_name, klass: self)
|
470
422
|
end
|
471
423
|
|
472
|
-
def arel_attribute(name, table = arel_table) # :nodoc:
|
473
|
-
table[name]
|
474
|
-
end
|
475
|
-
deprecate :arel_attribute
|
476
|
-
|
477
424
|
def predicate_builder # :nodoc:
|
478
425
|
@predicate_builder ||= PredicateBuilder.new(table_metadata)
|
479
426
|
end
|
@@ -482,10 +429,6 @@ module ActiveRecord
|
|
482
429
|
TypeCaster::Map.new(self)
|
483
430
|
end
|
484
431
|
|
485
|
-
def _internal? # :nodoc:
|
486
|
-
false
|
487
|
-
end
|
488
|
-
|
489
432
|
def cached_find_by_statement(key, &block) # :nodoc:
|
490
433
|
cache = @find_by_statement_cache[connection.prepared_statements]
|
491
434
|
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
@@ -543,7 +486,7 @@ module ActiveRecord
|
|
543
486
|
# post.init_with(coder)
|
544
487
|
# post.title # => 'hello world'
|
545
488
|
def init_with(coder, &block)
|
546
|
-
coder = LegacyYamlAdapter.convert(
|
489
|
+
coder = LegacyYamlAdapter.convert(coder)
|
547
490
|
attributes = self.class.yaml_encoder.decode(coder)
|
548
491
|
init_with_attributes(attributes, coder["new_record"], &block)
|
549
492
|
end
|
@@ -645,6 +588,8 @@ module ActiveRecord
|
|
645
588
|
# Delegates to id in order to allow two records of the same type and id to work with something like:
|
646
589
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
647
590
|
def hash
|
591
|
+
id = self.id
|
592
|
+
|
648
593
|
if id
|
649
594
|
self.class.hash ^ id.hash
|
650
595
|
else
|
@@ -696,11 +641,37 @@ module ActiveRecord
|
|
696
641
|
# if the record tries to lazily load an association.
|
697
642
|
#
|
698
643
|
# user = User.first
|
699
|
-
# user.strict_loading!
|
700
|
-
# user.comments
|
644
|
+
# user.strict_loading! # => true
|
645
|
+
# user.comments
|
701
646
|
# => ActiveRecord::StrictLoadingViolationError
|
702
|
-
|
703
|
-
|
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
|
704
675
|
end
|
705
676
|
|
706
677
|
# Marks this record as read only.
|
@@ -717,11 +688,11 @@ module ActiveRecord
|
|
717
688
|
# We check defined?(@attributes) not to issue warnings if the object is
|
718
689
|
# allocated but not initialized.
|
719
690
|
inspection = if defined?(@attributes) && @attributes
|
720
|
-
self.class.attribute_names.
|
691
|
+
self.class.attribute_names.filter_map do |name|
|
721
692
|
if _has_attribute?(name)
|
722
693
|
"#{name}: #{attribute_for_inspect(name)}"
|
723
694
|
end
|
724
|
-
end.
|
695
|
+
end.join(", ")
|
725
696
|
else
|
726
697
|
"not initialized"
|
727
698
|
end
|
@@ -778,16 +749,20 @@ module ActiveRecord
|
|
778
749
|
end
|
779
750
|
|
780
751
|
def init_internals
|
781
|
-
@primary_key = self.class.primary_key
|
782
752
|
@readonly = false
|
783
753
|
@previously_new_record = false
|
784
754
|
@destroyed = false
|
785
755
|
@marked_for_destruction = false
|
786
756
|
@destroyed_by_association = nil
|
787
757
|
@_start_transaction_state = nil
|
788
|
-
@strict_loading = self.class.strict_loading_by_default
|
789
758
|
|
790
|
-
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
|
791
766
|
end
|
792
767
|
|
793
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,
|