activerecord 6.1.7 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1516 -1019
- data/MIT-LICENSE +1 -1
- data/README.rdoc +17 -18
- data/lib/active_record/aggregations.rb +17 -14
- data/lib/active_record/association_relation.rb +1 -11
- data/lib/active_record/associations/association.rb +50 -19
- data/lib/active_record/associations/association_scope.rb +17 -12
- data/lib/active_record/associations/belongs_to_association.rb +28 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +11 -5
- data/lib/active_record/associations/builder/belongs_to.rb +40 -14
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +6 -2
- data/lib/active_record/associations/collection_association.rb +35 -31
- data/lib/active_record/associations/collection_proxy.rb +30 -15
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +28 -18
- data/lib/active_record/associations/has_many_through_association.rb +12 -7
- data/lib/active_record/associations/has_one_association.rb +20 -10
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +26 -16
- data/lib/active_record/associations/preloader/association.rb +207 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +50 -14
- data/lib/active_record/associations/preloader.rb +50 -121
- data/lib/active_record/associations/singular_association.rb +9 -3
- data/lib/active_record/associations/through_association.rb +25 -14
- data/lib/active_record/associations.rb +423 -289
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
- data/lib/active_record/attribute_methods/dirty.rb +61 -14
- data/lib/active_record/attribute_methods/primary_key.rb +78 -26
- data/lib/active_record/attribute_methods/query.rb +31 -19
- data/lib/active_record/attribute_methods/read.rb +25 -10
- data/lib/active_record/attribute_methods/serialization.rb +194 -37
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +10 -13
- data/lib/active_record/attribute_methods.rb +121 -40
- data/lib/active_record/attributes.rb +27 -38
- data/lib/active_record/autosave_association.rb +61 -30
- data/lib/active_record/base.rb +25 -2
- data/lib/active_record/callbacks.rb +18 -34
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -46
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +96 -590
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -51
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +77 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +360 -136
- data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
- data/lib/active_record/connection_adapters/abstract_adapter.rb +622 -149
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +285 -156
- data/lib/active_record/connection_adapters/column.rb +13 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
- data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +104 -53
- data/lib/active_record/connection_adapters/pool_config.rb +20 -11
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +18 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +86 -52
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +381 -69
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +492 -230
- data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +65 -53
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +294 -102
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
- data/lib/active_record/connection_adapters.rb +9 -6
- data/lib/active_record/connection_handling.rb +107 -136
- data/lib/active_record/core.rb +194 -224
- data/lib/active_record/counter_cache.rb +46 -25
- data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
- data/lib/active_record/database_configurations/database_config.rb +21 -12
- data/lib/active_record/database_configurations/hash_config.rb +84 -16
- data/lib/active_record/database_configurations/url_config.rb +18 -12
- data/lib/active_record/database_configurations.rb +95 -59
- data/lib/active_record/delegated_type.rb +61 -15
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +224 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +151 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +172 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +92 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +96 -0
- data/lib/active_record/encryption.rb +56 -0
- data/lib/active_record/enum.rb +156 -62
- data/lib/active_record/errors.rb +171 -15
- data/lib/active_record/explain.rb +23 -3
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +70 -14
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +131 -86
- data/lib/active_record/future_result.rb +164 -0
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +81 -29
- data/lib/active_record/insert_all.rb +133 -20
- data/lib/active_record/integration.rb +11 -10
- data/lib/active_record/internal_metadata.rb +117 -33
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +36 -21
- data/lib/active_record/locking/pessimistic.rb +15 -6
- data/lib/active_record/log_subscriber.rb +52 -19
- data/lib/active_record/marshalling.rb +56 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
- data/lib/active_record/middleware/database_selector.rb +23 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +108 -13
- data/lib/active_record/migration/compatibility.rb +221 -48
- data/lib/active_record/migration/default_strategy.rb +23 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +355 -171
- data/lib/active_record/model_schema.rb +116 -97
- data/lib/active_record/nested_attributes.rb +36 -15
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/normalization.rb +159 -0
- data/lib/active_record/persistence.rb +405 -85
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +3 -21
- data/lib/active_record/query_logs.rb +174 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +29 -6
- data/lib/active_record/railtie.rb +219 -43
- data/lib/active_record/railties/controller_runtime.rb +13 -9
- data/lib/active_record/railties/databases.rake +185 -249
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +41 -3
- data/lib/active_record/reflection.rb +229 -80
- data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
- data/lib/active_record/relation/batches.rb +192 -63
- data/lib/active_record/relation/calculations.rb +211 -90
- data/lib/active_record/relation/delegation.rb +27 -13
- data/lib/active_record/relation/finder_methods.rb +108 -51
- data/lib/active_record/relation/merger.rb +22 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +27 -20
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +654 -127
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +20 -3
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +262 -120
- data/lib/active_record/result.rb +37 -11
- data/lib/active_record/runtime_registry.rb +18 -13
- data/lib/active_record/sanitization.rb +65 -20
- data/lib/active_record/schema.rb +36 -22
- data/lib/active_record/schema_dumper.rb +73 -24
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +72 -15
- data/lib/active_record/scoping/named.rb +5 -13
- data/lib/active_record/scoping.rb +65 -34
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +10 -8
- data/lib/active_record/store.rb +10 -10
- data/lib/active_record/suppressor.rb +13 -15
- data/lib/active_record/table_metadata.rb +16 -3
- data/lib/active_record/tasks/database_tasks.rb +225 -136
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
- data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +116 -96
- data/lib/active_record/timestamp.rb +28 -17
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +48 -27
- data/lib/active_record/translation.rb +3 -3
- data/lib/active_record/type/adapter_specific_registry.rb +32 -14
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +9 -5
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +4 -4
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +51 -6
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +335 -32
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/and.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -1
- data/lib/arel/nodes/bound_sql_literal.rb +61 -0
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/homogeneous_in.rb +0 -8
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +5 -0
- data/lib/arel/predications.rb +13 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +9 -6
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +16 -3
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +139 -19
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +18 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +92 -13
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -67
data/lib/active_record/core.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/enumerable"
|
4
|
-
require "active_support/core_ext/
|
5
|
-
require "active_support/core_ext/string/filters"
|
4
|
+
require "active_support/core_ext/module/delegation"
|
6
5
|
require "active_support/parameter_filter"
|
7
6
|
require "concurrent/map"
|
8
7
|
|
9
8
|
module ActiveRecord
|
9
|
+
# = Active Record \Core
|
10
10
|
module Core
|
11
11
|
extend ActiveSupport::Concern
|
12
|
+
include ActiveModel::Access
|
12
13
|
|
13
14
|
included do
|
14
15
|
##
|
@@ -17,26 +18,32 @@ module ActiveRecord
|
|
17
18
|
# Accepts a logger conforming to the interface of Log4r which is then
|
18
19
|
# passed on to any new database connections made and which can be
|
19
20
|
# retrieved on both a class and instance level by calling +logger+.
|
20
|
-
|
21
|
+
class_attribute :logger, instance_writer: false
|
21
22
|
|
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
|
23
|
+
class_attribute :_destroy_association_async_job, instance_accessor: false, default: "ActiveRecord::DestroyAssociationAsyncJob"
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
# The job class used to destroy associations in the background.
|
26
|
+
def self.destroy_association_async_job
|
27
|
+
if _destroy_association_async_job.is_a?(String)
|
28
|
+
self._destroy_association_async_job = _destroy_association_async_job.constantize
|
29
|
+
end
|
30
|
+
_destroy_association_async_job
|
31
|
+
rescue NameError => error
|
32
|
+
raise NameError, "Unable to load destroy_association_async_job: #{error.message}"
|
33
|
+
end
|
34
|
+
|
35
|
+
singleton_class.alias_method :destroy_association_async_job=, :_destroy_association_async_job=
|
36
|
+
delegate :destroy_association_async_job, to: :class
|
34
37
|
|
35
38
|
##
|
36
39
|
# :singleton-method:
|
37
40
|
#
|
38
|
-
# Specifies the
|
39
|
-
|
41
|
+
# Specifies the maximum number of records that will be destroyed in a
|
42
|
+
# single background job by the <tt>dependent: :destroy_async</tt>
|
43
|
+
# association option. When +nil+ (default), all dependent records will be
|
44
|
+
# destroyed in a single background job. If specified, the records to be
|
45
|
+
# destroyed will be split into multiple background jobs.
|
46
|
+
class_attribute :destroy_association_async_batch_size, instance_writer: false, instance_predicate: false, default: nil
|
40
47
|
|
41
48
|
##
|
42
49
|
# Contains the database configuration - as is typically stored in config/database.yml -
|
@@ -46,19 +53,19 @@ module ActiveRecord
|
|
46
53
|
#
|
47
54
|
# development:
|
48
55
|
# adapter: sqlite3
|
49
|
-
# database:
|
56
|
+
# database: storage/development.sqlite3
|
50
57
|
#
|
51
58
|
# production:
|
52
59
|
# adapter: sqlite3
|
53
|
-
# database:
|
60
|
+
# database: storage/production.sqlite3
|
54
61
|
#
|
55
62
|
# ...would result in ActiveRecord::Base.configurations to look like this:
|
56
63
|
#
|
57
64
|
# #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
|
58
65
|
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
59
|
-
# @name="primary", @config={adapter: "sqlite3", database: "
|
66
|
+
# @name="primary", @config={adapter: "sqlite3", database: "storage/development.sqlite3"}>,
|
60
67
|
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
|
61
|
-
# @name="primary", @config={adapter: "sqlite3", database: "
|
68
|
+
# @name="primary", @config={adapter: "sqlite3", database: "storage/production.sqlite3"}>
|
62
69
|
# ]>
|
63
70
|
def self.configurations=(config)
|
64
71
|
@@configurations = ActiveRecord::DatabaseConfigurations.new(config)
|
@@ -72,80 +79,19 @@ module ActiveRecord
|
|
72
79
|
|
73
80
|
##
|
74
81
|
# :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
|
82
|
+
# Force enumeration of all columns in SELECT statements.
|
83
|
+
# e.g. <tt>SELECT first_name, last_name FROM ...</tt> instead of <tt>SELECT * FROM ...</tt>
|
84
|
+
# This avoids +PreparedStatementCacheExpired+ errors when a column is added
|
85
|
+
# to the database while the app is running.
|
86
|
+
class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false
|
133
87
|
|
134
88
|
class_attribute :belongs_to_required_by_default, instance_accessor: false
|
135
89
|
|
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
90
|
class_attribute :strict_loading_by_default, instance_accessor: false, default: false
|
143
91
|
|
144
|
-
|
92
|
+
class_attribute :has_many_inversing, instance_accessor: false, default: false
|
145
93
|
|
146
|
-
|
147
|
-
|
148
|
-
mattr_accessor :has_many_inversing, instance_accessor: false, default: false
|
94
|
+
class_attribute :run_commit_callbacks_on_first_saved_instances_in_transaction, instance_accessor: false, default: true
|
149
95
|
|
150
96
|
class_attribute :default_connection_handler, instance_writer: false
|
151
97
|
|
@@ -153,40 +99,35 @@ module ActiveRecord
|
|
153
99
|
|
154
100
|
class_attribute :default_shard, instance_writer: false
|
155
101
|
|
156
|
-
|
157
|
-
|
158
|
-
# Application configurable boolean that instructs the YAML Coder to use
|
159
|
-
# an unsafe load if set to true.
|
160
|
-
mattr_accessor :use_yaml_unsafe_load, instance_writer: false, default: false
|
102
|
+
class_attribute :shard_selector, instance_accessor: false, default: nil
|
161
103
|
|
162
|
-
|
163
|
-
|
164
|
-
|
104
|
+
def self.application_record_class? # :nodoc:
|
105
|
+
if ActiveRecord.application_record_class
|
106
|
+
self == ActiveRecord.application_record_class
|
107
|
+
else
|
108
|
+
if defined?(ApplicationRecord) && self == ApplicationRecord
|
109
|
+
true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
165
113
|
|
166
114
|
self.filter_attributes = []
|
167
115
|
|
168
116
|
def self.connection_handler
|
169
|
-
|
117
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
|
170
118
|
end
|
171
119
|
|
172
120
|
def self.connection_handler=(handler)
|
173
|
-
|
121
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
|
174
122
|
end
|
175
123
|
|
176
|
-
def self.
|
177
|
-
|
178
|
-
raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
|
179
|
-
end
|
180
|
-
|
181
|
-
@@connection_handlers ||= {}
|
124
|
+
def self.asynchronous_queries_session # :nodoc:
|
125
|
+
asynchronous_queries_tracker.current_session
|
182
126
|
end
|
183
127
|
|
184
|
-
def self.
|
185
|
-
|
186
|
-
|
187
|
-
end
|
188
|
-
|
189
|
-
@@connection_handlers = handlers
|
128
|
+
def self.asynchronous_queries_tracker # :nodoc:
|
129
|
+
ActiveSupport::IsolatedExecutionState[:active_record_asynchronous_queries_tracker] ||= \
|
130
|
+
AsynchronousQueriesTracker.new
|
190
131
|
end
|
191
132
|
|
192
133
|
# Returns the symbol representing the current connected role.
|
@@ -199,16 +140,12 @@ module ActiveRecord
|
|
199
140
|
# ActiveRecord::Base.current_role #=> :reading
|
200
141
|
# end
|
201
142
|
def self.current_role
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
connected_to_stack.reverse_each do |hash|
|
206
|
-
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
207
|
-
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_classes)
|
208
|
-
end
|
209
|
-
|
210
|
-
default_role
|
143
|
+
connected_to_stack.reverse_each do |hash|
|
144
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
145
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
|
211
146
|
end
|
147
|
+
|
148
|
+
default_role
|
212
149
|
end
|
213
150
|
|
214
151
|
# Returns the symbol representing the current connected shard.
|
@@ -223,7 +160,7 @@ module ActiveRecord
|
|
223
160
|
def self.current_shard
|
224
161
|
connected_to_stack.reverse_each do |hash|
|
225
162
|
return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
|
226
|
-
return hash[:shard] if hash[:shard] && hash[:klasses].include?(
|
163
|
+
return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
|
227
164
|
end
|
228
165
|
|
229
166
|
default_shard
|
@@ -240,24 +177,20 @@ module ActiveRecord
|
|
240
177
|
# ActiveRecord::Base.current_preventing_writes #=> false
|
241
178
|
# end
|
242
179
|
def self.current_preventing_writes
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
connected_to_stack.reverse_each do |hash|
|
247
|
-
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
|
248
|
-
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_classes)
|
249
|
-
end
|
250
|
-
|
251
|
-
false
|
180
|
+
connected_to_stack.reverse_each do |hash|
|
181
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
|
182
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
|
252
183
|
end
|
184
|
+
|
185
|
+
false
|
253
186
|
end
|
254
187
|
|
255
188
|
def self.connected_to_stack # :nodoc:
|
256
|
-
if connected_to_stack =
|
189
|
+
if connected_to_stack = ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack]
|
257
190
|
connected_to_stack
|
258
191
|
else
|
259
192
|
connected_to_stack = Concurrent::Array.new
|
260
|
-
|
193
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack] = connected_to_stack
|
261
194
|
connected_to_stack
|
262
195
|
end
|
263
196
|
end
|
@@ -266,7 +199,7 @@ module ActiveRecord
|
|
266
199
|
@connection_class = b
|
267
200
|
end
|
268
201
|
|
269
|
-
def self.connection_class # :nodoc
|
202
|
+
def self.connection_class # :nodoc:
|
270
203
|
@connection_class ||= false
|
271
204
|
end
|
272
205
|
|
@@ -274,7 +207,7 @@ module ActiveRecord
|
|
274
207
|
self.connection_class
|
275
208
|
end
|
276
209
|
|
277
|
-
def self.
|
210
|
+
def self.connection_class_for_self # :nodoc:
|
278
211
|
klass = self
|
279
212
|
|
280
213
|
until klass == Base
|
@@ -285,22 +218,14 @@ module ActiveRecord
|
|
285
218
|
klass
|
286
219
|
end
|
287
220
|
|
288
|
-
def self.allow_unsafe_raw_sql # :nodoc:
|
289
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 7.0")
|
290
|
-
end
|
291
|
-
|
292
|
-
def self.allow_unsafe_raw_sql=(value) # :nodoc:
|
293
|
-
ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 7.0")
|
294
|
-
end
|
295
|
-
|
296
221
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
297
|
-
self.default_role = writing_role
|
222
|
+
self.default_role = ActiveRecord.writing_role
|
298
223
|
self.default_shard = :default
|
299
224
|
|
300
225
|
def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
|
301
|
-
case action_on_strict_loading_violation
|
226
|
+
case ActiveRecord.action_on_strict_loading_violation
|
302
227
|
when :raise
|
303
|
-
message =
|
228
|
+
message = reflection.strict_loading_violation_message(owner)
|
304
229
|
raise ActiveRecord::StrictLoadingViolationError.new(message)
|
305
230
|
when :log
|
306
231
|
name = "strict_loading_violation.active_record"
|
@@ -314,19 +239,6 @@ module ActiveRecord
|
|
314
239
|
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
|
315
240
|
end
|
316
241
|
|
317
|
-
def inherited(child_class) # :nodoc:
|
318
|
-
# initialize cache at class definition for thread safety
|
319
|
-
child_class.initialize_find_by_cache
|
320
|
-
unless child_class.base_class?
|
321
|
-
klass = self
|
322
|
-
until klass.base_class?
|
323
|
-
klass.initialize_find_by_cache
|
324
|
-
klass = klass.superclass
|
325
|
-
end
|
326
|
-
end
|
327
|
-
super
|
328
|
-
end
|
329
|
-
|
330
242
|
def find(*ids) # :nodoc:
|
331
243
|
# We don't have cache keys for this stuff yet
|
332
244
|
return super unless ids.length == 1
|
@@ -336,14 +248,8 @@ module ActiveRecord
|
|
336
248
|
|
337
249
|
return super if StatementCache.unsupported_value?(id)
|
338
250
|
|
339
|
-
|
340
|
-
|
341
|
-
statement = cached_find_by_statement(key) { |params|
|
342
|
-
where(key => params.bind).limit(1)
|
343
|
-
}
|
344
|
-
|
345
|
-
statement.execute([id], connection).first ||
|
346
|
-
raise(RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id))
|
251
|
+
cached_find_by([primary_key], [id]) ||
|
252
|
+
raise(RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}", name, primary_key, id))
|
347
253
|
end
|
348
254
|
|
349
255
|
def find_by(*args) # :nodoc:
|
@@ -375,21 +281,11 @@ module ActiveRecord
|
|
375
281
|
h[key] = value
|
376
282
|
end
|
377
283
|
|
378
|
-
keys
|
379
|
-
statement = cached_find_by_statement(keys) { |params|
|
380
|
-
wheres = keys.index_with { params.bind }
|
381
|
-
where(wheres).limit(1)
|
382
|
-
}
|
383
|
-
|
384
|
-
begin
|
385
|
-
statement.execute(hash.values, connection).first
|
386
|
-
rescue TypeError
|
387
|
-
raise ActiveRecord::StatementInvalid
|
388
|
-
end
|
284
|
+
cached_find_by(hash.keys, hash.values)
|
389
285
|
end
|
390
286
|
|
391
287
|
def find_by!(*args) # :nodoc:
|
392
|
-
find_by(*args) ||
|
288
|
+
find_by(*args) || where(*args).raise_record_not_found_exception!
|
393
289
|
end
|
394
290
|
|
395
291
|
def initialize_generated_modules # :nodoc:
|
@@ -408,10 +304,10 @@ module ActiveRecord
|
|
408
304
|
|
409
305
|
# Returns columns which shouldn't be exposed while calling +#inspect+.
|
410
306
|
def filter_attributes
|
411
|
-
if
|
412
|
-
@filter_attributes
|
413
|
-
else
|
307
|
+
if @filter_attributes.nil?
|
414
308
|
superclass.filter_attributes
|
309
|
+
else
|
310
|
+
@filter_attributes
|
415
311
|
end
|
416
312
|
end
|
417
313
|
|
@@ -422,13 +318,13 @@ module ActiveRecord
|
|
422
318
|
end
|
423
319
|
|
424
320
|
def inspection_filter # :nodoc:
|
425
|
-
if
|
321
|
+
if @filter_attributes.nil?
|
322
|
+
superclass.inspection_filter
|
323
|
+
else
|
426
324
|
@inspection_filter ||= begin
|
427
325
|
mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
|
428
326
|
ActiveSupport::ParameterFilter.new(@filter_attributes, mask: mask)
|
429
327
|
end
|
430
|
-
else
|
431
|
-
superclass.inspection_filter
|
432
328
|
end
|
433
329
|
end
|
434
330
|
|
@@ -448,25 +344,11 @@ module ActiveRecord
|
|
448
344
|
end
|
449
345
|
end
|
450
346
|
|
451
|
-
#
|
452
|
-
def ===(object) # :nodoc:
|
453
|
-
object.is_a?(self)
|
454
|
-
end
|
455
|
-
|
456
|
-
# Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
|
457
|
-
#
|
458
|
-
# class Post < ActiveRecord::Base
|
459
|
-
# scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
|
460
|
-
# end
|
347
|
+
# Returns an instance of +Arel::Table+ loaded with the current table name.
|
461
348
|
def arel_table # :nodoc:
|
462
349
|
@arel_table ||= Arel::Table.new(table_name, klass: self)
|
463
350
|
end
|
464
351
|
|
465
|
-
def arel_attribute(name, table = arel_table) # :nodoc:
|
466
|
-
table[name]
|
467
|
-
end
|
468
|
-
deprecate :arel_attribute
|
469
|
-
|
470
352
|
def predicate_builder # :nodoc:
|
471
353
|
@predicate_builder ||= PredicateBuilder.new(table_metadata)
|
472
354
|
end
|
@@ -475,16 +357,34 @@ module ActiveRecord
|
|
475
357
|
TypeCaster::Map.new(self)
|
476
358
|
end
|
477
359
|
|
478
|
-
def _internal? # :nodoc:
|
479
|
-
false
|
480
|
-
end
|
481
|
-
|
482
360
|
def cached_find_by_statement(key, &block) # :nodoc:
|
483
361
|
cache = @find_by_statement_cache[connection.prepared_statements]
|
484
362
|
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
485
363
|
end
|
486
364
|
|
487
365
|
private
|
366
|
+
def inherited(subclass)
|
367
|
+
super
|
368
|
+
|
369
|
+
# initialize cache at class definition for thread safety
|
370
|
+
subclass.initialize_find_by_cache
|
371
|
+
unless subclass.base_class?
|
372
|
+
klass = self
|
373
|
+
until klass.base_class?
|
374
|
+
klass.initialize_find_by_cache
|
375
|
+
klass = klass.superclass
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
subclass.class_eval do
|
380
|
+
@arel_table = nil
|
381
|
+
@predicate_builder = nil
|
382
|
+
@inspection_filter = nil
|
383
|
+
@filter_attributes = nil
|
384
|
+
@generated_association_methods = nil
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
488
388
|
def relation
|
489
389
|
relation = Relation.create(self)
|
490
390
|
|
@@ -498,6 +398,19 @@ module ActiveRecord
|
|
498
398
|
def table_metadata
|
499
399
|
TableMetadata.new(self, arel_table)
|
500
400
|
end
|
401
|
+
|
402
|
+
def cached_find_by(keys, values)
|
403
|
+
statement = cached_find_by_statement(keys) { |params|
|
404
|
+
wheres = keys.index_with { params.bind }
|
405
|
+
where(wheres).limit(1)
|
406
|
+
}
|
407
|
+
|
408
|
+
begin
|
409
|
+
statement.execute(values, connection).first
|
410
|
+
rescue TypeError
|
411
|
+
raise ActiveRecord::StatementInvalid
|
412
|
+
end
|
413
|
+
end
|
501
414
|
end
|
502
415
|
|
503
416
|
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
@@ -505,7 +418,7 @@ module ActiveRecord
|
|
505
418
|
# In both instances, valid attribute keys are determined by the column names of the associated table --
|
506
419
|
# hence you can't have attributes that aren't part of the table columns.
|
507
420
|
#
|
508
|
-
# ==== Example
|
421
|
+
# ==== Example
|
509
422
|
# # Instantiates a single new object
|
510
423
|
# User.new(first_name: 'Jamie')
|
511
424
|
def initialize(attributes = nil)
|
@@ -536,7 +449,7 @@ module ActiveRecord
|
|
536
449
|
# post.init_with(coder)
|
537
450
|
# post.title # => 'hello world'
|
538
451
|
def init_with(coder, &block)
|
539
|
-
coder = LegacyYamlAdapter.convert(
|
452
|
+
coder = LegacyYamlAdapter.convert(coder)
|
540
453
|
attributes = self.class.yaml_encoder.decode(coder)
|
541
454
|
init_with_attributes(attributes, coder["new_record"], &block)
|
542
455
|
end
|
@@ -583,12 +496,17 @@ module ActiveRecord
|
|
583
496
|
# only, not its associations. The extent of a "deep" copy is application
|
584
497
|
# specific and is therefore left to the application to implement according
|
585
498
|
# to its need.
|
586
|
-
# The dup method does not preserve the timestamps (created|updated)_(at|on)
|
499
|
+
# The dup method does not preserve the timestamps (created|updated)_(at|on)
|
500
|
+
# and locking column.
|
587
501
|
|
588
502
|
##
|
589
503
|
def initialize_dup(other) # :nodoc:
|
590
504
|
@attributes = @attributes.deep_dup
|
591
|
-
|
505
|
+
if self.class.composite_primary_key?
|
506
|
+
@primary_key.each { |key| @attributes.reset(key) }
|
507
|
+
else
|
508
|
+
@attributes.reset(@primary_key)
|
509
|
+
end
|
592
510
|
|
593
511
|
_run_initialize_callbacks
|
594
512
|
|
@@ -630,7 +548,7 @@ module ActiveRecord
|
|
630
548
|
def ==(comparison_object)
|
631
549
|
super ||
|
632
550
|
comparison_object.instance_of?(self.class) &&
|
633
|
-
|
551
|
+
primary_key_values_present? &&
|
634
552
|
comparison_object.id == id
|
635
553
|
end
|
636
554
|
alias :eql? :==
|
@@ -638,7 +556,9 @@ module ActiveRecord
|
|
638
556
|
# Delegates to id in order to allow two records of the same type and id to work with something like:
|
639
557
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
640
558
|
def hash
|
641
|
-
|
559
|
+
id = self.id
|
560
|
+
|
561
|
+
if primary_key_values_present?
|
642
562
|
self.class.hash ^ id.hash
|
643
563
|
else
|
644
564
|
super
|
@@ -689,11 +609,45 @@ module ActiveRecord
|
|
689
609
|
# if the record tries to lazily load an association.
|
690
610
|
#
|
691
611
|
# user = User.first
|
692
|
-
# user.strict_loading!
|
612
|
+
# user.strict_loading! # => true
|
613
|
+
# user.address.city
|
614
|
+
# => ActiveRecord::StrictLoadingViolationError
|
693
615
|
# user.comments.to_a
|
694
616
|
# => ActiveRecord::StrictLoadingViolationError
|
695
|
-
|
696
|
-
|
617
|
+
#
|
618
|
+
# ==== Parameters
|
619
|
+
#
|
620
|
+
# * +value+ - Boolean specifying whether to enable or disable strict loading.
|
621
|
+
# * <tt>:mode</tt> - Symbol specifying strict loading mode. Defaults to :all. Using
|
622
|
+
# :n_plus_one_only mode will only raise an error if an association that
|
623
|
+
# will lead to an n plus one query is lazily loaded.
|
624
|
+
#
|
625
|
+
# ==== Examples
|
626
|
+
#
|
627
|
+
# user = User.first
|
628
|
+
# user.strict_loading!(false) # => false
|
629
|
+
# user.address.city # => "Tatooine"
|
630
|
+
# user.comments.to_a # => [#<Comment:0x00...]
|
631
|
+
#
|
632
|
+
# user.strict_loading!(mode: :n_plus_one_only)
|
633
|
+
# user.address.city # => "Tatooine"
|
634
|
+
# user.comments.to_a # => [#<Comment:0x00...]
|
635
|
+
# user.comments.first.ratings.to_a
|
636
|
+
# => ActiveRecord::StrictLoadingViolationError
|
637
|
+
def strict_loading!(value = true, mode: :all)
|
638
|
+
unless [:all, :n_plus_one_only].include?(mode)
|
639
|
+
raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only] but #{mode.inspect} was provided."
|
640
|
+
end
|
641
|
+
|
642
|
+
@strict_loading_mode = mode
|
643
|
+
@strict_loading = value
|
644
|
+
end
|
645
|
+
|
646
|
+
attr_reader :strict_loading_mode
|
647
|
+
|
648
|
+
# Returns +true+ if the record uses strict_loading with +:n_plus_one_only+ mode enabled.
|
649
|
+
def strict_loading_n_plus_one_only?
|
650
|
+
@strict_loading_mode == :n_plus_one_only
|
697
651
|
end
|
698
652
|
|
699
653
|
# Marks this record as read only.
|
@@ -710,11 +664,11 @@ module ActiveRecord
|
|
710
664
|
# We check defined?(@attributes) not to issue warnings if the object is
|
711
665
|
# allocated but not initialized.
|
712
666
|
inspection = if defined?(@attributes) && @attributes
|
713
|
-
|
667
|
+
attribute_names.filter_map do |name|
|
714
668
|
if _has_attribute?(name)
|
715
669
|
"#{name}: #{attribute_for_inspect(name)}"
|
716
670
|
end
|
717
|
-
end.
|
671
|
+
end.join(", ")
|
718
672
|
else
|
719
673
|
"not initialized"
|
720
674
|
end
|
@@ -747,15 +701,26 @@ module ActiveRecord
|
|
747
701
|
end
|
748
702
|
end
|
749
703
|
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
704
|
+
##
|
705
|
+
# :method: values_at
|
706
|
+
#
|
707
|
+
# :call-seq: values_at(*methods)
|
708
|
+
#
|
755
709
|
# Returns an array of the values returned by the given methods.
|
756
|
-
|
757
|
-
|
758
|
-
|
710
|
+
#
|
711
|
+
#--
|
712
|
+
# Implemented by ActiveModel::Access#values_at.
|
713
|
+
|
714
|
+
##
|
715
|
+
# :method: slice
|
716
|
+
#
|
717
|
+
# :call-seq: slice(*methods)
|
718
|
+
#
|
719
|
+
# Returns a hash of the given methods with their names as keys and returned
|
720
|
+
# values as values.
|
721
|
+
#
|
722
|
+
#--
|
723
|
+
# Implemented by ActiveModel::Access#slice.
|
759
724
|
|
760
725
|
private
|
761
726
|
# +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
|
@@ -771,16 +736,21 @@ module ActiveRecord
|
|
771
736
|
end
|
772
737
|
|
773
738
|
def init_internals
|
774
|
-
@primary_key = self.class.primary_key
|
775
739
|
@readonly = false
|
776
740
|
@previously_new_record = false
|
777
741
|
@destroyed = false
|
778
742
|
@marked_for_destruction = false
|
779
743
|
@destroyed_by_association = nil
|
780
744
|
@_start_transaction_state = nil
|
781
|
-
@strict_loading = self.class.strict_loading_by_default
|
782
745
|
|
783
|
-
self.class
|
746
|
+
klass = self.class
|
747
|
+
|
748
|
+
@primary_key = klass.primary_key
|
749
|
+
@strict_loading = klass.strict_loading_by_default
|
750
|
+
@strict_loading_mode = :all
|
751
|
+
|
752
|
+
klass.define_attribute_methods
|
753
|
+
klass.generate_alias_attributes
|
784
754
|
end
|
785
755
|
|
786
756
|
def initialize_internals_callback
|