activerecord 6.1.6 → 7.1.2
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 +1627 -983
- data/MIT-LICENSE +1 -1
- data/README.rdoc +18 -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 +439 -305
- 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 +73 -22
- 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 -34
- 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 +172 -50
- 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 -138
- data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
- data/lib/active_record/connection_adapters/abstract_adapter.rb +631 -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 +151 -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 +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +89 -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/money.rb +3 -2
- 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 +394 -74
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +509 -247
- 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 +72 -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 +99 -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 +202 -223
- 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 +157 -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 +154 -63
- 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 +135 -22
- data/lib/active_record/integration.rb +11 -10
- data/lib/active_record/internal_metadata.rb +119 -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 +112 -14
- 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/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +358 -171
- data/lib/active_record/model_schema.rb +120 -101
- data/lib/active_record/nested_attributes.rb +37 -18
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/normalization.rb +167 -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 +188 -252
- 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 +241 -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 +219 -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 +16 -11
- 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 +123 -99
- data/lib/active_record/timestamp.rb +29 -18
- 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 +1 -9
- 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 +93 -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,42 +1,50 @@
|
|
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
|
##
|
15
16
|
# :singleton-method:
|
16
17
|
#
|
17
|
-
# Accepts a logger conforming to the interface of Log4r
|
18
|
-
# passed on to any new database
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
#
|
26
|
-
|
27
|
-
|
18
|
+
# Accepts a logger conforming to the interface of Log4r or the default
|
19
|
+
# Ruby +Logger+ class, which is then passed on to any new database
|
20
|
+
# connections made. You can retrieve this logger by calling +logger+ on
|
21
|
+
# either an Active Record model class or an Active Record model instance.
|
22
|
+
class_attribute :logger, instance_writer: false
|
23
|
+
|
24
|
+
class_attribute :_destroy_association_async_job, instance_accessor: false, default: "ActiveRecord::DestroyAssociationAsyncJob"
|
25
|
+
|
26
|
+
# The job class used to destroy associations in the background.
|
27
|
+
def self.destroy_association_async_job
|
28
|
+
if _destroy_association_async_job.is_a?(String)
|
29
|
+
self._destroy_association_async_job = _destroy_association_async_job.constantize
|
30
|
+
end
|
31
|
+
_destroy_association_async_job
|
32
|
+
rescue NameError => error
|
33
|
+
raise NameError, "Unable to load destroy_association_async_job: #{error.message}"
|
34
|
+
end
|
28
35
|
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
# Specifies the names of the queues used by background jobs.
|
33
|
-
mattr_accessor :queues, instance_accessor: false, default: {}
|
36
|
+
singleton_class.alias_method :destroy_association_async_job=, :_destroy_association_async_job=
|
37
|
+
delegate :destroy_association_async_job, to: :class
|
34
38
|
|
35
39
|
##
|
36
40
|
# :singleton-method:
|
37
41
|
#
|
38
|
-
# Specifies the
|
39
|
-
|
42
|
+
# Specifies the maximum number of records that will be destroyed in a
|
43
|
+
# single background job by the <tt>dependent: :destroy_async</tt>
|
44
|
+
# association option. When +nil+ (default), all dependent records will be
|
45
|
+
# destroyed in a single background job. If specified, the records to be
|
46
|
+
# destroyed will be split into multiple background jobs.
|
47
|
+
class_attribute :destroy_association_async_batch_size, instance_writer: false, instance_predicate: false, default: nil
|
40
48
|
|
41
49
|
##
|
42
50
|
# Contains the database configuration - as is typically stored in config/database.yml -
|
@@ -46,19 +54,19 @@ module ActiveRecord
|
|
46
54
|
#
|
47
55
|
# development:
|
48
56
|
# adapter: sqlite3
|
49
|
-
# database:
|
57
|
+
# database: storage/development.sqlite3
|
50
58
|
#
|
51
59
|
# production:
|
52
60
|
# adapter: sqlite3
|
53
|
-
# database:
|
61
|
+
# database: storage/production.sqlite3
|
54
62
|
#
|
55
63
|
# ...would result in ActiveRecord::Base.configurations to look like this:
|
56
64
|
#
|
57
65
|
# #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
|
58
66
|
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
59
|
-
# @name="primary", @config={adapter: "sqlite3", database: "
|
67
|
+
# @name="primary", @config={adapter: "sqlite3", database: "storage/development.sqlite3"}>,
|
60
68
|
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
|
61
|
-
# @name="primary", @config={adapter: "sqlite3", database: "
|
69
|
+
# @name="primary", @config={adapter: "sqlite3", database: "storage/production.sqlite3"}>
|
62
70
|
# ]>
|
63
71
|
def self.configurations=(config)
|
64
72
|
@@configurations = ActiveRecord::DatabaseConfigurations.new(config)
|
@@ -72,80 +80,19 @@ module ActiveRecord
|
|
72
80
|
|
73
81
|
##
|
74
82
|
# :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
|
83
|
+
# Force enumeration of all columns in SELECT statements.
|
84
|
+
# e.g. <tt>SELECT first_name, last_name FROM ...</tt> instead of <tt>SELECT * FROM ...</tt>
|
85
|
+
# This avoids +PreparedStatementCacheExpired+ errors when a column is added
|
86
|
+
# to the database while the app is running.
|
87
|
+
class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false
|
133
88
|
|
134
89
|
class_attribute :belongs_to_required_by_default, instance_accessor: false
|
135
90
|
|
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
91
|
class_attribute :strict_loading_by_default, instance_accessor: false, default: false
|
143
92
|
|
144
|
-
|
145
|
-
|
146
|
-
mattr_accessor :reading_role, instance_accessor: false, default: :reading
|
93
|
+
class_attribute :has_many_inversing, instance_accessor: false, default: false
|
147
94
|
|
148
|
-
|
95
|
+
class_attribute :run_commit_callbacks_on_first_saved_instances_in_transaction, instance_accessor: false, default: true
|
149
96
|
|
150
97
|
class_attribute :default_connection_handler, instance_writer: false
|
151
98
|
|
@@ -153,32 +100,35 @@ module ActiveRecord
|
|
153
100
|
|
154
101
|
class_attribute :default_shard, instance_writer: false
|
155
102
|
|
156
|
-
|
103
|
+
class_attribute :shard_selector, instance_accessor: false, default: nil
|
104
|
+
|
105
|
+
def self.application_record_class? # :nodoc:
|
106
|
+
if ActiveRecord.application_record_class
|
107
|
+
self == ActiveRecord.application_record_class
|
108
|
+
else
|
109
|
+
if defined?(ApplicationRecord) && self == ApplicationRecord
|
110
|
+
true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
157
114
|
|
158
115
|
self.filter_attributes = []
|
159
116
|
|
160
117
|
def self.connection_handler
|
161
|
-
|
118
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
|
162
119
|
end
|
163
120
|
|
164
121
|
def self.connection_handler=(handler)
|
165
|
-
|
122
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
|
166
123
|
end
|
167
124
|
|
168
|
-
def self.
|
169
|
-
|
170
|
-
raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
|
171
|
-
end
|
172
|
-
|
173
|
-
@@connection_handlers ||= {}
|
125
|
+
def self.asynchronous_queries_session # :nodoc:
|
126
|
+
asynchronous_queries_tracker.current_session
|
174
127
|
end
|
175
128
|
|
176
|
-
def self.
|
177
|
-
|
178
|
-
|
179
|
-
end
|
180
|
-
|
181
|
-
@@connection_handlers = handlers
|
129
|
+
def self.asynchronous_queries_tracker # :nodoc:
|
130
|
+
ActiveSupport::IsolatedExecutionState[:active_record_asynchronous_queries_tracker] ||= \
|
131
|
+
AsynchronousQueriesTracker.new
|
182
132
|
end
|
183
133
|
|
184
134
|
# Returns the symbol representing the current connected role.
|
@@ -191,16 +141,12 @@ module ActiveRecord
|
|
191
141
|
# ActiveRecord::Base.current_role #=> :reading
|
192
142
|
# end
|
193
143
|
def self.current_role
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
connected_to_stack.reverse_each do |hash|
|
198
|
-
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
199
|
-
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_classes)
|
200
|
-
end
|
201
|
-
|
202
|
-
default_role
|
144
|
+
connected_to_stack.reverse_each do |hash|
|
145
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
146
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
|
203
147
|
end
|
148
|
+
|
149
|
+
default_role
|
204
150
|
end
|
205
151
|
|
206
152
|
# Returns the symbol representing the current connected shard.
|
@@ -215,7 +161,7 @@ module ActiveRecord
|
|
215
161
|
def self.current_shard
|
216
162
|
connected_to_stack.reverse_each do |hash|
|
217
163
|
return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
|
218
|
-
return hash[:shard] if hash[:shard] && hash[:klasses].include?(
|
164
|
+
return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
|
219
165
|
end
|
220
166
|
|
221
167
|
default_shard
|
@@ -232,24 +178,20 @@ module ActiveRecord
|
|
232
178
|
# ActiveRecord::Base.current_preventing_writes #=> false
|
233
179
|
# end
|
234
180
|
def self.current_preventing_writes
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
connected_to_stack.reverse_each do |hash|
|
239
|
-
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?(connection_classes)
|
241
|
-
end
|
242
|
-
|
243
|
-
false
|
181
|
+
connected_to_stack.reverse_each do |hash|
|
182
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
|
183
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
|
244
184
|
end
|
185
|
+
|
186
|
+
false
|
245
187
|
end
|
246
188
|
|
247
189
|
def self.connected_to_stack # :nodoc:
|
248
|
-
if connected_to_stack =
|
190
|
+
if connected_to_stack = ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack]
|
249
191
|
connected_to_stack
|
250
192
|
else
|
251
193
|
connected_to_stack = Concurrent::Array.new
|
252
|
-
|
194
|
+
ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack] = connected_to_stack
|
253
195
|
connected_to_stack
|
254
196
|
end
|
255
197
|
end
|
@@ -258,7 +200,7 @@ module ActiveRecord
|
|
258
200
|
@connection_class = b
|
259
201
|
end
|
260
202
|
|
261
|
-
def self.connection_class # :nodoc
|
203
|
+
def self.connection_class # :nodoc:
|
262
204
|
@connection_class ||= false
|
263
205
|
end
|
264
206
|
|
@@ -266,7 +208,7 @@ module ActiveRecord
|
|
266
208
|
self.connection_class
|
267
209
|
end
|
268
210
|
|
269
|
-
def self.
|
211
|
+
def self.connection_class_for_self # :nodoc:
|
270
212
|
klass = self
|
271
213
|
|
272
214
|
until klass == Base
|
@@ -277,22 +219,14 @@ module ActiveRecord
|
|
277
219
|
klass
|
278
220
|
end
|
279
221
|
|
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
222
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
289
|
-
self.default_role = writing_role
|
223
|
+
self.default_role = ActiveRecord.writing_role
|
290
224
|
self.default_shard = :default
|
291
225
|
|
292
226
|
def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
|
293
|
-
case action_on_strict_loading_violation
|
227
|
+
case ActiveRecord.action_on_strict_loading_violation
|
294
228
|
when :raise
|
295
|
-
message =
|
229
|
+
message = reflection.strict_loading_violation_message(owner)
|
296
230
|
raise ActiveRecord::StrictLoadingViolationError.new(message)
|
297
231
|
when :log
|
298
232
|
name = "strict_loading_violation.active_record"
|
@@ -306,19 +240,6 @@ module ActiveRecord
|
|
306
240
|
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
|
307
241
|
end
|
308
242
|
|
309
|
-
def inherited(child_class) # :nodoc:
|
310
|
-
# initialize cache at class definition for thread safety
|
311
|
-
child_class.initialize_find_by_cache
|
312
|
-
unless child_class.base_class?
|
313
|
-
klass = self
|
314
|
-
until klass.base_class?
|
315
|
-
klass.initialize_find_by_cache
|
316
|
-
klass = klass.superclass
|
317
|
-
end
|
318
|
-
end
|
319
|
-
super
|
320
|
-
end
|
321
|
-
|
322
243
|
def find(*ids) # :nodoc:
|
323
244
|
# We don't have cache keys for this stuff yet
|
324
245
|
return super unless ids.length == 1
|
@@ -328,14 +249,8 @@ module ActiveRecord
|
|
328
249
|
|
329
250
|
return super if StatementCache.unsupported_value?(id)
|
330
251
|
|
331
|
-
|
332
|
-
|
333
|
-
statement = cached_find_by_statement(key) { |params|
|
334
|
-
where(key => params.bind).limit(1)
|
335
|
-
}
|
336
|
-
|
337
|
-
statement.execute([id], connection).first ||
|
338
|
-
raise(RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id))
|
252
|
+
cached_find_by([primary_key], [id]) ||
|
253
|
+
raise(RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}", name, primary_key, id))
|
339
254
|
end
|
340
255
|
|
341
256
|
def find_by(*args) # :nodoc:
|
@@ -367,21 +282,11 @@ module ActiveRecord
|
|
367
282
|
h[key] = value
|
368
283
|
end
|
369
284
|
|
370
|
-
keys
|
371
|
-
statement = cached_find_by_statement(keys) { |params|
|
372
|
-
wheres = keys.index_with { params.bind }
|
373
|
-
where(wheres).limit(1)
|
374
|
-
}
|
375
|
-
|
376
|
-
begin
|
377
|
-
statement.execute(hash.values, connection).first
|
378
|
-
rescue TypeError
|
379
|
-
raise ActiveRecord::StatementInvalid
|
380
|
-
end
|
285
|
+
cached_find_by(hash.keys, hash.values)
|
381
286
|
end
|
382
287
|
|
383
288
|
def find_by!(*args) # :nodoc:
|
384
|
-
find_by(*args) ||
|
289
|
+
find_by(*args) || where(*args).raise_record_not_found_exception!
|
385
290
|
end
|
386
291
|
|
387
292
|
def initialize_generated_modules # :nodoc:
|
@@ -400,10 +305,10 @@ module ActiveRecord
|
|
400
305
|
|
401
306
|
# Returns columns which shouldn't be exposed while calling +#inspect+.
|
402
307
|
def filter_attributes
|
403
|
-
if
|
404
|
-
@filter_attributes
|
405
|
-
else
|
308
|
+
if @filter_attributes.nil?
|
406
309
|
superclass.filter_attributes
|
310
|
+
else
|
311
|
+
@filter_attributes
|
407
312
|
end
|
408
313
|
end
|
409
314
|
|
@@ -414,13 +319,13 @@ module ActiveRecord
|
|
414
319
|
end
|
415
320
|
|
416
321
|
def inspection_filter # :nodoc:
|
417
|
-
if
|
322
|
+
if @filter_attributes.nil?
|
323
|
+
superclass.inspection_filter
|
324
|
+
else
|
418
325
|
@inspection_filter ||= begin
|
419
326
|
mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
|
420
327
|
ActiveSupport::ParameterFilter.new(@filter_attributes, mask: mask)
|
421
328
|
end
|
422
|
-
else
|
423
|
-
superclass.inspection_filter
|
424
329
|
end
|
425
330
|
end
|
426
331
|
|
@@ -440,25 +345,11 @@ module ActiveRecord
|
|
440
345
|
end
|
441
346
|
end
|
442
347
|
|
443
|
-
#
|
444
|
-
def ===(object) # :nodoc:
|
445
|
-
object.is_a?(self)
|
446
|
-
end
|
447
|
-
|
448
|
-
# 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
|
348
|
+
# Returns an instance of +Arel::Table+ loaded with the current table name.
|
453
349
|
def arel_table # :nodoc:
|
454
350
|
@arel_table ||= Arel::Table.new(table_name, klass: self)
|
455
351
|
end
|
456
352
|
|
457
|
-
def arel_attribute(name, table = arel_table) # :nodoc:
|
458
|
-
table[name]
|
459
|
-
end
|
460
|
-
deprecate :arel_attribute
|
461
|
-
|
462
353
|
def predicate_builder # :nodoc:
|
463
354
|
@predicate_builder ||= PredicateBuilder.new(table_metadata)
|
464
355
|
end
|
@@ -467,16 +358,34 @@ module ActiveRecord
|
|
467
358
|
TypeCaster::Map.new(self)
|
468
359
|
end
|
469
360
|
|
470
|
-
def _internal? # :nodoc:
|
471
|
-
false
|
472
|
-
end
|
473
|
-
|
474
361
|
def cached_find_by_statement(key, &block) # :nodoc:
|
475
362
|
cache = @find_by_statement_cache[connection.prepared_statements]
|
476
363
|
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
477
364
|
end
|
478
365
|
|
479
366
|
private
|
367
|
+
def inherited(subclass)
|
368
|
+
super
|
369
|
+
|
370
|
+
# initialize cache at class definition for thread safety
|
371
|
+
subclass.initialize_find_by_cache
|
372
|
+
unless subclass.base_class?
|
373
|
+
klass = self
|
374
|
+
until klass.base_class?
|
375
|
+
klass.initialize_find_by_cache
|
376
|
+
klass = klass.superclass
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
subclass.class_eval do
|
381
|
+
@arel_table = nil
|
382
|
+
@predicate_builder = nil
|
383
|
+
@inspection_filter = nil
|
384
|
+
@filter_attributes = nil
|
385
|
+
@generated_association_methods = nil
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
480
389
|
def relation
|
481
390
|
relation = Relation.create(self)
|
482
391
|
|
@@ -490,6 +399,19 @@ module ActiveRecord
|
|
490
399
|
def table_metadata
|
491
400
|
TableMetadata.new(self, arel_table)
|
492
401
|
end
|
402
|
+
|
403
|
+
def cached_find_by(keys, values)
|
404
|
+
statement = cached_find_by_statement(keys) { |params|
|
405
|
+
wheres = keys.index_with { params.bind }
|
406
|
+
where(wheres).limit(1)
|
407
|
+
}
|
408
|
+
|
409
|
+
begin
|
410
|
+
statement.execute(values, connection).first
|
411
|
+
rescue TypeError
|
412
|
+
raise ActiveRecord::StatementInvalid
|
413
|
+
end
|
414
|
+
end
|
493
415
|
end
|
494
416
|
|
495
417
|
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
@@ -497,7 +419,7 @@ module ActiveRecord
|
|
497
419
|
# In both instances, valid attribute keys are determined by the column names of the associated table --
|
498
420
|
# hence you can't have attributes that aren't part of the table columns.
|
499
421
|
#
|
500
|
-
# ==== Example
|
422
|
+
# ==== Example
|
501
423
|
# # Instantiates a single new object
|
502
424
|
# User.new(first_name: 'Jamie')
|
503
425
|
def initialize(attributes = nil)
|
@@ -528,7 +450,7 @@ module ActiveRecord
|
|
528
450
|
# post.init_with(coder)
|
529
451
|
# post.title # => 'hello world'
|
530
452
|
def init_with(coder, &block)
|
531
|
-
coder = LegacyYamlAdapter.convert(
|
453
|
+
coder = LegacyYamlAdapter.convert(coder)
|
532
454
|
attributes = self.class.yaml_encoder.decode(coder)
|
533
455
|
init_with_attributes(attributes, coder["new_record"], &block)
|
534
456
|
end
|
@@ -575,12 +497,17 @@ module ActiveRecord
|
|
575
497
|
# only, not its associations. The extent of a "deep" copy is application
|
576
498
|
# specific and is therefore left to the application to implement according
|
577
499
|
# to its need.
|
578
|
-
# The dup method does not preserve the timestamps (created|updated)_(at|on)
|
500
|
+
# The dup method does not preserve the timestamps (created|updated)_(at|on)
|
501
|
+
# and locking column.
|
579
502
|
|
580
503
|
##
|
581
504
|
def initialize_dup(other) # :nodoc:
|
582
505
|
@attributes = @attributes.deep_dup
|
583
|
-
|
506
|
+
if self.class.composite_primary_key?
|
507
|
+
@primary_key.each { |key| @attributes.reset(key) }
|
508
|
+
else
|
509
|
+
@attributes.reset(@primary_key)
|
510
|
+
end
|
584
511
|
|
585
512
|
_run_initialize_callbacks
|
586
513
|
|
@@ -610,6 +537,27 @@ module ActiveRecord
|
|
610
537
|
coder["active_record_yaml_version"] = 2
|
611
538
|
end
|
612
539
|
|
540
|
+
##
|
541
|
+
# :method: slice
|
542
|
+
#
|
543
|
+
# :call-seq: slice(*methods)
|
544
|
+
#
|
545
|
+
# Returns a hash of the given methods with their names as keys and returned
|
546
|
+
# values as values.
|
547
|
+
#
|
548
|
+
#--
|
549
|
+
# Implemented by ActiveModel::Access#slice.
|
550
|
+
|
551
|
+
##
|
552
|
+
# :method: values_at
|
553
|
+
#
|
554
|
+
# :call-seq: values_at(*methods)
|
555
|
+
#
|
556
|
+
# Returns an array of the values returned by the given methods.
|
557
|
+
#
|
558
|
+
#--
|
559
|
+
# Implemented by ActiveModel::Access#values_at.
|
560
|
+
|
613
561
|
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
614
562
|
# is of the same type and +self+ has an ID and it is equal to +comparison_object.id+.
|
615
563
|
#
|
@@ -622,7 +570,7 @@ module ActiveRecord
|
|
622
570
|
def ==(comparison_object)
|
623
571
|
super ||
|
624
572
|
comparison_object.instance_of?(self.class) &&
|
625
|
-
|
573
|
+
primary_key_values_present? &&
|
626
574
|
comparison_object.id == id
|
627
575
|
end
|
628
576
|
alias :eql? :==
|
@@ -630,7 +578,9 @@ module ActiveRecord
|
|
630
578
|
# Delegates to id in order to allow two records of the same type and id to work with something like:
|
631
579
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
632
580
|
def hash
|
633
|
-
|
581
|
+
id = self.id
|
582
|
+
|
583
|
+
if primary_key_values_present?
|
634
584
|
self.class.hash ^ id.hash
|
635
585
|
else
|
636
586
|
super
|
@@ -681,11 +631,45 @@ module ActiveRecord
|
|
681
631
|
# if the record tries to lazily load an association.
|
682
632
|
#
|
683
633
|
# user = User.first
|
684
|
-
# user.strict_loading!
|
634
|
+
# user.strict_loading! # => true
|
635
|
+
# user.address.city
|
636
|
+
# => ActiveRecord::StrictLoadingViolationError
|
685
637
|
# user.comments.to_a
|
686
638
|
# => ActiveRecord::StrictLoadingViolationError
|
687
|
-
|
688
|
-
|
639
|
+
#
|
640
|
+
# ==== Parameters
|
641
|
+
#
|
642
|
+
# * +value+ - Boolean specifying whether to enable or disable strict loading.
|
643
|
+
# * <tt>:mode</tt> - Symbol specifying strict loading mode. Defaults to :all. Using
|
644
|
+
# :n_plus_one_only mode will only raise an error if an association that
|
645
|
+
# will lead to an n plus one query is lazily loaded.
|
646
|
+
#
|
647
|
+
# ==== Examples
|
648
|
+
#
|
649
|
+
# user = User.first
|
650
|
+
# user.strict_loading!(false) # => false
|
651
|
+
# user.address.city # => "Tatooine"
|
652
|
+
# user.comments.to_a # => [#<Comment:0x00...]
|
653
|
+
#
|
654
|
+
# user.strict_loading!(mode: :n_plus_one_only)
|
655
|
+
# user.address.city # => "Tatooine"
|
656
|
+
# user.comments.to_a # => [#<Comment:0x00...]
|
657
|
+
# user.comments.first.ratings.to_a
|
658
|
+
# => ActiveRecord::StrictLoadingViolationError
|
659
|
+
def strict_loading!(value = true, mode: :all)
|
660
|
+
unless [:all, :n_plus_one_only].include?(mode)
|
661
|
+
raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only] but #{mode.inspect} was provided."
|
662
|
+
end
|
663
|
+
|
664
|
+
@strict_loading_mode = mode
|
665
|
+
@strict_loading = value
|
666
|
+
end
|
667
|
+
|
668
|
+
attr_reader :strict_loading_mode
|
669
|
+
|
670
|
+
# Returns +true+ if the record uses strict_loading with +:n_plus_one_only+ mode enabled.
|
671
|
+
def strict_loading_n_plus_one_only?
|
672
|
+
@strict_loading_mode == :n_plus_one_only
|
689
673
|
end
|
690
674
|
|
691
675
|
# Marks this record as read only.
|
@@ -702,11 +686,11 @@ module ActiveRecord
|
|
702
686
|
# We check defined?(@attributes) not to issue warnings if the object is
|
703
687
|
# allocated but not initialized.
|
704
688
|
inspection = if defined?(@attributes) && @attributes
|
705
|
-
|
689
|
+
attribute_names.filter_map do |name|
|
706
690
|
if _has_attribute?(name)
|
707
691
|
"#{name}: #{attribute_for_inspect(name)}"
|
708
692
|
end
|
709
|
-
end.
|
693
|
+
end.join(", ")
|
710
694
|
else
|
711
695
|
"not initialized"
|
712
696
|
end
|
@@ -739,16 +723,6 @@ module ActiveRecord
|
|
739
723
|
end
|
740
724
|
end
|
741
725
|
|
742
|
-
# Returns a hash of the given methods with their names as keys and returned values as values.
|
743
|
-
def slice(*methods)
|
744
|
-
methods.flatten.index_with { |method| public_send(method) }.with_indifferent_access
|
745
|
-
end
|
746
|
-
|
747
|
-
# Returns an array of the values returned by the given methods.
|
748
|
-
def values_at(*methods)
|
749
|
-
methods.flatten.map! { |method| public_send(method) }
|
750
|
-
end
|
751
|
-
|
752
726
|
private
|
753
727
|
# +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
|
754
728
|
# the array, and then rescues from the possible +NoMethodError+. If those elements are
|
@@ -763,16 +737,21 @@ module ActiveRecord
|
|
763
737
|
end
|
764
738
|
|
765
739
|
def init_internals
|
766
|
-
@primary_key = self.class.primary_key
|
767
740
|
@readonly = false
|
768
741
|
@previously_new_record = false
|
769
742
|
@destroyed = false
|
770
743
|
@marked_for_destruction = false
|
771
744
|
@destroyed_by_association = nil
|
772
745
|
@_start_transaction_state = nil
|
773
|
-
@strict_loading = self.class.strict_loading_by_default
|
774
746
|
|
775
|
-
self.class
|
747
|
+
klass = self.class
|
748
|
+
|
749
|
+
@primary_key = klass.primary_key
|
750
|
+
@strict_loading = klass.strict_loading_by_default
|
751
|
+
@strict_loading_mode = :all
|
752
|
+
|
753
|
+
klass.define_attribute_methods
|
754
|
+
klass.generate_alias_attributes
|
776
755
|
end
|
777
756
|
|
778
757
|
def initialize_internals_callback
|