activerecord 7.0.8.7 → 7.2.2.1
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 +631 -1944
- data/MIT-LICENSE +1 -1
- data/README.rdoc +29 -29
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +16 -13
- data/lib/active_record/association_relation.rb +2 -2
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +35 -12
- data/lib/active_record/associations/association_scope.rb +16 -9
- data/lib/active_record/associations/belongs_to_association.rb +23 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +3 -3
- data/lib/active_record/associations/builder/belongs_to.rb +22 -8
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +26 -14
- data/lib/active_record/associations/collection_proxy.rb +29 -11
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +21 -14
- data/lib/active_record/associations/has_many_through_association.rb +17 -7
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
- data/lib/active_record/associations/join_dependency.rb +10 -10
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +33 -8
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/preloader.rb +13 -10
- data/lib/active_record/associations/singular_association.rb +7 -1
- data/lib/active_record/associations/through_association.rb +22 -11
- data/lib/active_record/associations.rb +354 -485
- data/lib/active_record/attribute_assignment.rb +0 -4
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +53 -35
- data/lib/active_record/attribute_methods/primary_key.rb +45 -25
- data/lib/active_record/attribute_methods/query.rb +28 -16
- data/lib/active_record/attribute_methods/read.rb +8 -7
- data/lib/active_record/attribute_methods/serialization.rb +131 -32
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
- data/lib/active_record/attribute_methods/write.rb +6 -6
- data/lib/active_record/attribute_methods.rb +148 -33
- data/lib/active_record/attributes.rb +64 -50
- data/lib/active_record/autosave_association.rb +69 -37
- data/lib/active_record/base.rb +9 -5
- data/lib/active_record/callbacks.rb +11 -25
- 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 -42
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +123 -131
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +4 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +323 -88
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +160 -45
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +217 -63
- data/lib/active_record/connection_adapters/abstract/quoting.rb +72 -63
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +307 -129
- data/lib/active_record/connection_adapters/abstract/transaction.rb +367 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +510 -111
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +278 -125
- data/lib/active_record/connection_adapters/column.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +26 -139
- data/lib/active_record/connection_adapters/mysql/quoting.rb +53 -54
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +25 -13
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +101 -68
- data/lib/active_record/connection_adapters/pool_config.rb +20 -10
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +100 -43
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +65 -61
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +151 -2
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +370 -63
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +367 -201
- data/lib/active_record/connection_adapters/schema_cache.rb +302 -79
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +60 -43
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +45 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +14 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +50 -8
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -110
- 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 +229 -0
- data/lib/active_record/connection_adapters.rb +124 -1
- data/lib/active_record/connection_handling.rb +96 -104
- data/lib/active_record/core.rb +251 -176
- data/lib/active_record/counter_cache.rb +68 -34
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
- data/lib/active_record/database_configurations/database_config.rb +26 -5
- data/lib/active_record/database_configurations/hash_config.rb +52 -34
- data/lib/active_record/database_configurations/url_config.rb +37 -12
- data/lib/active_record/database_configurations.rb +87 -34
- data/lib/active_record/delegated_type.rb +39 -10
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
- data/lib/active_record/encryption/config.rb +25 -1
- data/lib/active_record/encryption/configurable.rb +12 -19
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +5 -1
- data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
- data/lib/active_record/encryption/encryptable_record.rb +45 -21
- data/lib/active_record/encryption/encrypted_attribute_type.rb +47 -12
- data/lib/active_record/encryption/encryptor.rb +18 -3
- data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
- data/lib/active_record/encryption/key_generator.rb +12 -1
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +6 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/properties.rb +3 -3
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +22 -21
- data/lib/active_record/encryption.rb +3 -0
- data/lib/active_record/enum.rb +129 -28
- data/lib/active_record/errors.rb +151 -31
- data/lib/active_record/explain.rb +21 -12
- 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 +29 -8
- data/lib/active_record/fixtures.rb +167 -97
- data/lib/active_record/future_result.rb +47 -8
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +34 -18
- data/lib/active_record/insert_all.rb +72 -22
- data/lib/active_record/integration.rb +11 -8
- data/lib/active_record/internal_metadata.rb +124 -20
- data/lib/active_record/locking/optimistic.rb +8 -7
- data/lib/active_record/locking/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +18 -22
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
- data/lib/active_record/middleware/database_selector.rb +6 -8
- data/lib/active_record/middleware/shard_selector.rb +3 -1
- data/lib/active_record/migration/command_recorder.rb +106 -8
- data/lib/active_record/migration/compatibility.rb +147 -5
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +234 -117
- data/lib/active_record/model_schema.rb +90 -102
- data/lib/active_record/nested_attributes.rb +48 -11
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +168 -339
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -25
- data/lib/active_record/query_logs.rb +92 -52
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +33 -8
- data/lib/active_record/railtie.rb +129 -85
- data/lib/active_record/railties/controller_runtime.rb +22 -7
- data/lib/active_record/railties/databases.rake +145 -154
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +32 -5
- data/lib/active_record/reflection.rb +267 -69
- data/lib/active_record/relation/batches/batch_enumerator.rb +20 -5
- data/lib/active_record/relation/batches.rb +198 -63
- data/lib/active_record/relation/calculations.rb +250 -93
- data/lib/active_record/relation/delegation.rb +30 -19
- data/lib/active_record/relation/finder_methods.rb +93 -18
- data/lib/active_record/relation/merger.rb +6 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +18 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +28 -16
- data/lib/active_record/relation/query_attribute.rb +2 -1
- data/lib/active_record/relation/query_methods.rb +576 -107
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +5 -4
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +580 -90
- data/lib/active_record/result.rb +49 -48
- data/lib/active_record/runtime_registry.rb +63 -1
- data/lib/active_record/sanitization.rb +70 -25
- data/lib/active_record/schema.rb +8 -7
- data/lib/active_record/schema_dumper.rb +63 -14
- data/lib/active_record/schema_migration.rb +75 -24
- data/lib/active_record/scoping/default.rb +15 -5
- data/lib/active_record/scoping/named.rb +3 -2
- data/lib/active_record/scoping.rb +2 -1
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/signed_id.rb +27 -6
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/store.rb +8 -8
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +1 -1
- data/lib/active_record/tasks/database_tasks.rb +190 -118
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
- data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
- data/lib/active_record/test_fixtures.rb +170 -155
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +31 -17
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +12 -7
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +106 -24
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +9 -3
- 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 +61 -11
- data/lib/active_record/validations.rb +12 -5
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +247 -33
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -7
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +115 -5
- data/lib/arel/nodes/sql_literal.rb +13 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes.rb +6 -2
- data/lib/arel/predications.rb +3 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/table.rb +9 -5
- data/lib/arel/tree_manager.rb +8 -3
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +17 -5
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +112 -34
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +21 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -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
- metadata +54 -12
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -63
data/lib/active_record/core.rb
CHANGED
@@ -1,29 +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
|
-
#
|
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.
|
20
22
|
class_attribute :logger, instance_writer: false
|
21
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
|
35
|
+
|
36
|
+
singleton_class.alias_method :destroy_association_async_job=, :_destroy_association_async_job=
|
37
|
+
delegate :destroy_association_async_job, to: :class
|
38
|
+
|
22
39
|
##
|
23
40
|
# :singleton-method:
|
24
41
|
#
|
25
|
-
# Specifies the
|
26
|
-
|
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
|
27
48
|
|
28
49
|
##
|
29
50
|
# Contains the database configuration - as is typically stored in config/database.yml -
|
@@ -33,26 +54,26 @@ module ActiveRecord
|
|
33
54
|
#
|
34
55
|
# development:
|
35
56
|
# adapter: sqlite3
|
36
|
-
# database:
|
57
|
+
# database: storage/development.sqlite3
|
37
58
|
#
|
38
59
|
# production:
|
39
60
|
# adapter: sqlite3
|
40
|
-
# database:
|
61
|
+
# database: storage/production.sqlite3
|
41
62
|
#
|
42
63
|
# ...would result in ActiveRecord::Base.configurations to look like this:
|
43
64
|
#
|
44
65
|
# #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
|
45
66
|
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
|
46
|
-
# @name="primary", @config={adapter: "sqlite3", database: "
|
67
|
+
# @name="primary", @config={adapter: "sqlite3", database: "storage/development.sqlite3"}>,
|
47
68
|
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
|
48
|
-
# @name="primary", @config={adapter: "sqlite3", database: "
|
69
|
+
# @name="primary", @config={adapter: "sqlite3", database: "storage/production.sqlite3"}>
|
49
70
|
# ]>
|
50
71
|
def self.configurations=(config)
|
51
72
|
@@configurations = ActiveRecord::DatabaseConfigurations.new(config)
|
52
73
|
end
|
53
74
|
self.configurations = {}
|
54
75
|
|
55
|
-
# Returns fully resolved ActiveRecord::DatabaseConfigurations object
|
76
|
+
# Returns a fully resolved ActiveRecord::DatabaseConfigurations object.
|
56
77
|
def self.configurations
|
57
78
|
@@configurations
|
58
79
|
end
|
@@ -71,6 +92,8 @@ module ActiveRecord
|
|
71
92
|
|
72
93
|
class_attribute :has_many_inversing, instance_accessor: false, default: false
|
73
94
|
|
95
|
+
class_attribute :run_commit_callbacks_on_first_saved_instances_in_transaction, instance_accessor: false, default: true
|
96
|
+
|
74
97
|
class_attribute :default_connection_handler, instance_writer: false
|
75
98
|
|
76
99
|
class_attribute :default_role, instance_writer: false
|
@@ -79,6 +102,21 @@ module ActiveRecord
|
|
79
102
|
|
80
103
|
class_attribute :shard_selector, instance_accessor: false, default: nil
|
81
104
|
|
105
|
+
##
|
106
|
+
# :singleton-method:
|
107
|
+
#
|
108
|
+
# Specifies the attributes that will be included in the output of the
|
109
|
+
# #inspect method:
|
110
|
+
#
|
111
|
+
# Post.attributes_for_inspect = [:id, :title]
|
112
|
+
# Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
|
113
|
+
#
|
114
|
+
# When set to `:all` inspect will list all the record's attributes:
|
115
|
+
#
|
116
|
+
# Post.attributes_for_inspect = :all
|
117
|
+
# Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
|
118
|
+
class_attribute :attributes_for_inspect, instance_accessor: false, default: :all
|
119
|
+
|
82
120
|
def self.application_record_class? # :nodoc:
|
83
121
|
if ActiveRecord.application_record_class
|
84
122
|
self == ActiveRecord.application_record_class
|
@@ -99,33 +137,6 @@ module ActiveRecord
|
|
99
137
|
ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
|
100
138
|
end
|
101
139
|
|
102
|
-
def self.connection_handlers
|
103
|
-
if ActiveRecord.legacy_connection_handling
|
104
|
-
else
|
105
|
-
raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
|
106
|
-
end
|
107
|
-
|
108
|
-
@@connection_handlers ||= {}
|
109
|
-
end
|
110
|
-
|
111
|
-
def self.connection_handlers=(handlers)
|
112
|
-
if ActiveRecord.legacy_connection_handling
|
113
|
-
ActiveSupport::Deprecation.warn(<<~MSG)
|
114
|
-
Using legacy connection handling is deprecated. Please set
|
115
|
-
`legacy_connection_handling` to `false` in your application.
|
116
|
-
|
117
|
-
The new connection handling does not support `connection_handlers`
|
118
|
-
getter and setter.
|
119
|
-
|
120
|
-
Read more about how to migrate at: https://guides.rubyonrails.org/active_record_multiple_databases.html#migrate-to-the-new-connection-handling
|
121
|
-
MSG
|
122
|
-
else
|
123
|
-
raise NotImplementedError, "The new connection handling does not support multiple connection handlers."
|
124
|
-
end
|
125
|
-
|
126
|
-
@@connection_handlers = handlers
|
127
|
-
end
|
128
|
-
|
129
140
|
def self.asynchronous_queries_session # :nodoc:
|
130
141
|
asynchronous_queries_tracker.current_session
|
131
142
|
end
|
@@ -145,16 +156,12 @@ module ActiveRecord
|
|
145
156
|
# ActiveRecord::Base.current_role #=> :reading
|
146
157
|
# end
|
147
158
|
def self.current_role
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
connected_to_stack.reverse_each do |hash|
|
152
|
-
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
153
|
-
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
|
154
|
-
end
|
155
|
-
|
156
|
-
default_role
|
159
|
+
connected_to_stack.reverse_each do |hash|
|
160
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
|
161
|
+
return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
|
157
162
|
end
|
163
|
+
|
164
|
+
default_role
|
158
165
|
end
|
159
166
|
|
160
167
|
# Returns the symbol representing the current connected shard.
|
@@ -186,16 +193,12 @@ module ActiveRecord
|
|
186
193
|
# ActiveRecord::Base.current_preventing_writes #=> false
|
187
194
|
# end
|
188
195
|
def self.current_preventing_writes
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
connected_to_stack.reverse_each do |hash|
|
193
|
-
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
|
194
|
-
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
|
195
|
-
end
|
196
|
-
|
197
|
-
false
|
196
|
+
connected_to_stack.reverse_each do |hash|
|
197
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
|
198
|
+
return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
|
198
199
|
end
|
200
|
+
|
201
|
+
false
|
199
202
|
end
|
200
203
|
|
201
204
|
def self.connected_to_stack # :nodoc:
|
@@ -252,19 +255,6 @@ module ActiveRecord
|
|
252
255
|
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
|
253
256
|
end
|
254
257
|
|
255
|
-
def inherited(child_class) # :nodoc:
|
256
|
-
# initialize cache at class definition for thread safety
|
257
|
-
child_class.initialize_find_by_cache
|
258
|
-
unless child_class.base_class?
|
259
|
-
klass = self
|
260
|
-
until klass.base_class?
|
261
|
-
klass.initialize_find_by_cache
|
262
|
-
klass = klass.superclass
|
263
|
-
end
|
264
|
-
end
|
265
|
-
super
|
266
|
-
end
|
267
|
-
|
268
258
|
def find(*ids) # :nodoc:
|
269
259
|
# We don't have cache keys for this stuff yet
|
270
260
|
return super unless ids.length == 1
|
@@ -274,14 +264,8 @@ module ActiveRecord
|
|
274
264
|
|
275
265
|
return super if StatementCache.unsupported_value?(id)
|
276
266
|
|
277
|
-
|
278
|
-
|
279
|
-
statement = cached_find_by_statement(key) { |params|
|
280
|
-
where(key => params.bind).limit(1)
|
281
|
-
}
|
282
|
-
|
283
|
-
statement.execute([id], connection).first ||
|
284
|
-
raise(RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id))
|
267
|
+
cached_find_by([primary_key], [id]) ||
|
268
|
+
raise(RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}", name, primary_key, id))
|
285
269
|
end
|
286
270
|
|
287
271
|
def find_by(*args) # :nodoc:
|
@@ -303,58 +287,38 @@ module ActiveRecord
|
|
303
287
|
elsif reflection.belongs_to? && !reflection.polymorphic?
|
304
288
|
key = reflection.join_foreign_key
|
305
289
|
pkey = reflection.join_primary_key
|
306
|
-
|
290
|
+
|
291
|
+
if pkey.is_a?(Array)
|
292
|
+
if pkey.all? { |attribute| value.respond_to?(attribute) }
|
293
|
+
value = pkey.map do |attribute|
|
294
|
+
if attribute == "id"
|
295
|
+
value.id_value
|
296
|
+
else
|
297
|
+
value.public_send(attribute)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
composite_primary_key = true
|
301
|
+
end
|
302
|
+
else
|
303
|
+
value = value.public_send(pkey) if value.respond_to?(pkey)
|
304
|
+
end
|
307
305
|
end
|
308
306
|
|
309
|
-
if !
|
307
|
+
if !composite_primary_key &&
|
308
|
+
(!columns_hash.key?(key) || StatementCache.unsupported_value?(value))
|
310
309
|
return super
|
311
310
|
end
|
312
311
|
|
313
312
|
h[key] = value
|
314
313
|
end
|
315
314
|
|
316
|
-
keys
|
317
|
-
statement = cached_find_by_statement(keys) { |params|
|
318
|
-
wheres = keys.index_with { params.bind }
|
319
|
-
where(wheres).limit(1)
|
320
|
-
}
|
321
|
-
|
322
|
-
begin
|
323
|
-
statement.execute(hash.values, connection).first
|
324
|
-
rescue TypeError
|
325
|
-
raise ActiveRecord::StatementInvalid
|
326
|
-
end
|
315
|
+
cached_find_by(hash.keys, hash.values)
|
327
316
|
end
|
328
317
|
|
329
318
|
def find_by!(*args) # :nodoc:
|
330
319
|
find_by(*args) || where(*args).raise_record_not_found_exception!
|
331
320
|
end
|
332
321
|
|
333
|
-
%w(
|
334
|
-
reading_role writing_role legacy_connection_handling default_timezone index_nested_attribute_errors
|
335
|
-
verbose_query_logs queues warn_on_records_fetched_greater_than maintain_test_schema
|
336
|
-
application_record_class action_on_strict_loading_violation schema_format error_on_ignored_order
|
337
|
-
timestamped_migrations dump_schema_after_migration dump_schemas suppress_multiple_database_warning
|
338
|
-
).each do |attr|
|
339
|
-
module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
340
|
-
def #{attr}
|
341
|
-
ActiveSupport::Deprecation.warn(<<~MSG)
|
342
|
-
ActiveRecord::Base.#{attr} is deprecated and will be removed in Rails 7.1.
|
343
|
-
Use `ActiveRecord.#{attr}` instead.
|
344
|
-
MSG
|
345
|
-
ActiveRecord.#{attr}
|
346
|
-
end
|
347
|
-
|
348
|
-
def #{attr}=(value)
|
349
|
-
ActiveSupport::Deprecation.warn(<<~MSG)
|
350
|
-
ActiveRecord::Base.#{attr}= is deprecated and will be removed in Rails 7.1.
|
351
|
-
Use `ActiveRecord.#{attr}=` instead.
|
352
|
-
MSG
|
353
|
-
ActiveRecord.#{attr} = value
|
354
|
-
end
|
355
|
-
RUBY
|
356
|
-
end
|
357
|
-
|
358
322
|
def initialize_generated_modules # :nodoc:
|
359
323
|
generated_association_methods
|
360
324
|
end
|
@@ -371,10 +335,10 @@ module ActiveRecord
|
|
371
335
|
|
372
336
|
# Returns columns which shouldn't be exposed while calling +#inspect+.
|
373
337
|
def filter_attributes
|
374
|
-
if
|
375
|
-
@filter_attributes
|
376
|
-
else
|
338
|
+
if @filter_attributes.nil?
|
377
339
|
superclass.filter_attributes
|
340
|
+
else
|
341
|
+
@filter_attributes
|
378
342
|
end
|
379
343
|
end
|
380
344
|
|
@@ -385,24 +349,24 @@ module ActiveRecord
|
|
385
349
|
end
|
386
350
|
|
387
351
|
def inspection_filter # :nodoc:
|
388
|
-
if
|
352
|
+
if @filter_attributes.nil?
|
353
|
+
superclass.inspection_filter
|
354
|
+
else
|
389
355
|
@inspection_filter ||= begin
|
390
356
|
mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
|
391
357
|
ActiveSupport::ParameterFilter.new(@filter_attributes, mask: mask)
|
392
358
|
end
|
393
|
-
else
|
394
|
-
superclass.inspection_filter
|
395
359
|
end
|
396
360
|
end
|
397
361
|
|
398
362
|
# Returns a string like 'Post(id:integer, title:string, body:text)'
|
399
363
|
def inspect # :nodoc:
|
400
|
-
if self == Base
|
364
|
+
if self == Base || singleton_class?
|
401
365
|
super
|
402
366
|
elsif abstract_class?
|
403
367
|
"#{super}(abstract)"
|
404
|
-
elsif !connected?
|
405
|
-
"#{super} (call '#{super}.
|
368
|
+
elsif !schema_loaded? && !connected?
|
369
|
+
"#{super} (call '#{super}.load_schema' to load schema informations)"
|
406
370
|
elsif table_exists?
|
407
371
|
attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
|
408
372
|
"#{super}(#{attr_list})"
|
@@ -411,12 +375,7 @@ module ActiveRecord
|
|
411
375
|
end
|
412
376
|
end
|
413
377
|
|
414
|
-
#
|
415
|
-
def ===(object) # :nodoc:
|
416
|
-
object.is_a?(self)
|
417
|
-
end
|
418
|
-
|
419
|
-
# Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
|
378
|
+
# Returns an instance of +Arel::Table+ loaded with the current table name.
|
420
379
|
def arel_table # :nodoc:
|
421
380
|
@arel_table ||= Arel::Table.new(table_name, klass: self)
|
422
381
|
end
|
@@ -429,12 +388,34 @@ module ActiveRecord
|
|
429
388
|
TypeCaster::Map.new(self)
|
430
389
|
end
|
431
390
|
|
432
|
-
def cached_find_by_statement(key, &block) # :nodoc:
|
391
|
+
def cached_find_by_statement(connection, key, &block) # :nodoc:
|
433
392
|
cache = @find_by_statement_cache[connection.prepared_statements]
|
434
393
|
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
435
394
|
end
|
436
395
|
|
437
396
|
private
|
397
|
+
def inherited(subclass)
|
398
|
+
super
|
399
|
+
|
400
|
+
# initialize cache at class definition for thread safety
|
401
|
+
subclass.initialize_find_by_cache
|
402
|
+
unless subclass.base_class?
|
403
|
+
klass = self
|
404
|
+
until klass.base_class?
|
405
|
+
klass.initialize_find_by_cache
|
406
|
+
klass = klass.superclass
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
subclass.class_eval do
|
411
|
+
@arel_table = nil
|
412
|
+
@predicate_builder = nil
|
413
|
+
@inspection_filter = nil
|
414
|
+
@filter_attributes ||= nil
|
415
|
+
@generated_association_methods ||= nil
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
438
419
|
def relation
|
439
420
|
relation = Relation.create(self)
|
440
421
|
|
@@ -448,6 +429,27 @@ module ActiveRecord
|
|
448
429
|
def table_metadata
|
449
430
|
TableMetadata.new(self, arel_table)
|
450
431
|
end
|
432
|
+
|
433
|
+
def cached_find_by(keys, values)
|
434
|
+
with_connection do |connection|
|
435
|
+
statement = cached_find_by_statement(connection, keys) { |params|
|
436
|
+
wheres = keys.index_with do |key|
|
437
|
+
if key.is_a?(Array)
|
438
|
+
[key.map { params.bind }]
|
439
|
+
else
|
440
|
+
params.bind
|
441
|
+
end
|
442
|
+
end
|
443
|
+
where(wheres).limit(1)
|
444
|
+
}
|
445
|
+
|
446
|
+
begin
|
447
|
+
statement.execute(values.flatten, connection, allow_retry: true).first
|
448
|
+
rescue TypeError
|
449
|
+
raise ActiveRecord::StatementInvalid
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
451
453
|
end
|
452
454
|
|
453
455
|
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
@@ -455,7 +457,7 @@ module ActiveRecord
|
|
455
457
|
# In both instances, valid attribute keys are determined by the column names of the associated table --
|
456
458
|
# hence you can't have attributes that aren't part of the table columns.
|
457
459
|
#
|
458
|
-
# ==== Example
|
460
|
+
# ==== Example
|
459
461
|
# # Instantiates a single new object
|
460
462
|
# User.new(first_name: 'Jamie')
|
461
463
|
def initialize(attributes = nil)
|
@@ -465,7 +467,7 @@ module ActiveRecord
|
|
465
467
|
init_internals
|
466
468
|
initialize_internals_callback
|
467
469
|
|
468
|
-
|
470
|
+
super
|
469
471
|
|
470
472
|
yield self if block_given?
|
471
473
|
_run_initialize_callbacks
|
@@ -533,12 +535,17 @@ module ActiveRecord
|
|
533
535
|
# only, not its associations. The extent of a "deep" copy is application
|
534
536
|
# specific and is therefore left to the application to implement according
|
535
537
|
# to its need.
|
536
|
-
# The dup method does not preserve the timestamps (created|updated)_(at|on)
|
538
|
+
# The dup method does not preserve the timestamps (created|updated)_(at|on)
|
539
|
+
# and locking column.
|
537
540
|
|
538
541
|
##
|
539
542
|
def initialize_dup(other) # :nodoc:
|
540
543
|
@attributes = @attributes.deep_dup
|
541
|
-
|
544
|
+
if self.class.composite_primary_key?
|
545
|
+
@primary_key.each { |key| @attributes.reset(key) }
|
546
|
+
else
|
547
|
+
@attributes.reset(@primary_key)
|
548
|
+
end
|
542
549
|
|
543
550
|
_run_initialize_callbacks
|
544
551
|
|
@@ -568,6 +575,35 @@ module ActiveRecord
|
|
568
575
|
coder["active_record_yaml_version"] = 2
|
569
576
|
end
|
570
577
|
|
578
|
+
##
|
579
|
+
# :method: slice
|
580
|
+
#
|
581
|
+
# :call-seq: slice(*methods)
|
582
|
+
#
|
583
|
+
# Returns a hash of the given methods with their names as keys and returned
|
584
|
+
# values as values.
|
585
|
+
#
|
586
|
+
# topic = Topic.new(title: "Budget", author_name: "Jason")
|
587
|
+
# topic.slice(:title, :author_name)
|
588
|
+
# => { "title" => "Budget", "author_name" => "Jason" }
|
589
|
+
#
|
590
|
+
#--
|
591
|
+
# Implemented by ActiveModel::Access#slice.
|
592
|
+
|
593
|
+
##
|
594
|
+
# :method: values_at
|
595
|
+
#
|
596
|
+
# :call-seq: values_at(*methods)
|
597
|
+
#
|
598
|
+
# Returns an array of the values returned by the given methods.
|
599
|
+
#
|
600
|
+
# topic = Topic.new(title: "Budget", author_name: "Jason")
|
601
|
+
# topic.values_at(:title, :author_name)
|
602
|
+
# => ["Budget", "Jason"]
|
603
|
+
#
|
604
|
+
#--
|
605
|
+
# Implemented by ActiveModel::Access#values_at.
|
606
|
+
|
571
607
|
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
572
608
|
# is of the same type and +self+ has an ID and it is equal to +comparison_object.id+.
|
573
609
|
#
|
@@ -580,7 +616,7 @@ module ActiveRecord
|
|
580
616
|
def ==(comparison_object)
|
581
617
|
super ||
|
582
618
|
comparison_object.instance_of?(self.class) &&
|
583
|
-
|
619
|
+
primary_key_values_present? &&
|
584
620
|
comparison_object.id == id
|
585
621
|
end
|
586
622
|
alias :eql? :==
|
@@ -590,7 +626,7 @@ module ActiveRecord
|
|
590
626
|
def hash
|
591
627
|
id = self.id
|
592
628
|
|
593
|
-
if
|
629
|
+
if primary_key_values_present?
|
594
630
|
self.class.hash ^ id.hash
|
595
631
|
else
|
596
632
|
super
|
@@ -642,25 +678,33 @@ module ActiveRecord
|
|
642
678
|
#
|
643
679
|
# user = User.first
|
644
680
|
# user.strict_loading! # => true
|
645
|
-
# user.
|
681
|
+
# user.address.city
|
682
|
+
# => ActiveRecord::StrictLoadingViolationError
|
683
|
+
# user.comments.to_a
|
646
684
|
# => ActiveRecord::StrictLoadingViolationError
|
647
685
|
#
|
648
|
-
#
|
686
|
+
# ==== Parameters
|
649
687
|
#
|
650
|
-
# * value - Boolean specifying whether to enable or disable strict loading.
|
651
|
-
# * mode - Symbol specifying strict loading mode. Defaults to :all. Using
|
652
|
-
#
|
653
|
-
#
|
688
|
+
# * +value+ - Boolean specifying whether to enable or disable strict loading.
|
689
|
+
# * <tt>:mode</tt> - Symbol specifying strict loading mode. Defaults to :all. Using
|
690
|
+
# :n_plus_one_only mode will only raise an error if an association that
|
691
|
+
# will lead to an n plus one query is lazily loaded.
|
654
692
|
#
|
655
|
-
#
|
693
|
+
# ==== Examples
|
656
694
|
#
|
657
695
|
# user = User.first
|
658
696
|
# user.strict_loading!(false) # => false
|
659
|
-
# user.
|
660
|
-
# => #<
|
697
|
+
# user.address.city # => "Tatooine"
|
698
|
+
# user.comments.to_a # => [#<Comment:0x00...]
|
699
|
+
#
|
700
|
+
# user.strict_loading!(mode: :n_plus_one_only)
|
701
|
+
# user.address.city # => "Tatooine"
|
702
|
+
# user.comments.to_a # => [#<Comment:0x00...]
|
703
|
+
# user.comments.first.ratings.to_a
|
704
|
+
# => ActiveRecord::StrictLoadingViolationError
|
661
705
|
def strict_loading!(value = true, mode: :all)
|
662
706
|
unless [:all, :n_plus_one_only].include?(mode)
|
663
|
-
raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only]."
|
707
|
+
raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only] but #{mode.inspect} was provided."
|
664
708
|
end
|
665
709
|
|
666
710
|
@strict_loading_mode = mode
|
@@ -674,7 +718,16 @@ module ActiveRecord
|
|
674
718
|
@strict_loading_mode == :n_plus_one_only
|
675
719
|
end
|
676
720
|
|
721
|
+
# Returns +true+ if the record uses strict_loading with +:all+ mode enabled.
|
722
|
+
def strict_loading_all?
|
723
|
+
@strict_loading_mode == :all
|
724
|
+
end
|
725
|
+
|
677
726
|
# Marks this record as read only.
|
727
|
+
#
|
728
|
+
# customer = Customer.first
|
729
|
+
# customer.readonly!
|
730
|
+
# customer.save # Raises an ActiveRecord::ReadOnlyRecord
|
678
731
|
def readonly!
|
679
732
|
@readonly = true
|
680
733
|
end
|
@@ -683,21 +736,28 @@ module ActiveRecord
|
|
683
736
|
self.class.connection_handler
|
684
737
|
end
|
685
738
|
|
686
|
-
# Returns the
|
739
|
+
# Returns the attributes of the record as a nicely formatted string.
|
740
|
+
#
|
741
|
+
# Post.first.inspect
|
742
|
+
# #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
|
743
|
+
#
|
744
|
+
# The attributes can be limited by setting <tt>.attributes_for_inspect</tt>.
|
745
|
+
#
|
746
|
+
# Post.attributes_for_inspect = [:id, :title]
|
747
|
+
# Post.first.inspect
|
748
|
+
# #=> "#<Post id: 1, title: "Hello, World!">"
|
687
749
|
def inspect
|
688
|
-
|
689
|
-
|
690
|
-
inspection = if defined?(@attributes) && @attributes
|
691
|
-
self.class.attribute_names.filter_map do |name|
|
692
|
-
if _has_attribute?(name)
|
693
|
-
"#{name}: #{attribute_for_inspect(name)}"
|
694
|
-
end
|
695
|
-
end.join(", ")
|
696
|
-
else
|
697
|
-
"not initialized"
|
698
|
-
end
|
750
|
+
inspect_with_attributes(attributes_for_inspect)
|
751
|
+
end
|
699
752
|
|
700
|
-
|
753
|
+
# Returns all attributes of the record as a nicely formatted string,
|
754
|
+
# ignoring <tt>.attributes_for_inspect</tt>.
|
755
|
+
#
|
756
|
+
# Post.first.full_inspect
|
757
|
+
# #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
|
758
|
+
#
|
759
|
+
def full_inspect
|
760
|
+
inspect_with_attributes(all_attributes_for_inspect)
|
701
761
|
end
|
702
762
|
|
703
763
|
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from <tt>pp record</tt>
|
@@ -705,17 +765,17 @@ module ActiveRecord
|
|
705
765
|
def pretty_print(pp)
|
706
766
|
return super if custom_inspect_method_defined?
|
707
767
|
pp.object_address_group(self) do
|
708
|
-
if
|
709
|
-
attr_names =
|
768
|
+
if @attributes
|
769
|
+
attr_names = attributes_for_inspect.select { |name| _has_attribute?(name.to_s) }
|
710
770
|
pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
|
771
|
+
attr_name = attr_name.to_s
|
711
772
|
pp.breakable " "
|
712
773
|
pp.group(1) do
|
713
774
|
pp.text attr_name
|
714
775
|
pp.text ":"
|
715
776
|
pp.breakable
|
716
|
-
value =
|
717
|
-
|
718
|
-
pp.pp value
|
777
|
+
value = attribute_for_inspect(attr_name)
|
778
|
+
pp.text value
|
719
779
|
end
|
720
780
|
end
|
721
781
|
else
|
@@ -725,16 +785,6 @@ module ActiveRecord
|
|
725
785
|
end
|
726
786
|
end
|
727
787
|
|
728
|
-
# Returns a hash of the given methods with their names as keys and returned values as values.
|
729
|
-
def slice(*methods)
|
730
|
-
methods.flatten.index_with { |method| public_send(method) }.with_indifferent_access
|
731
|
-
end
|
732
|
-
|
733
|
-
# Returns an array of the values returned by the given methods.
|
734
|
-
def values_at(*methods)
|
735
|
-
methods.flatten.map! { |method| public_send(method) }
|
736
|
-
end
|
737
|
-
|
738
788
|
private
|
739
789
|
# +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
|
740
790
|
# the array, and then rescues from the possible +NoMethodError+. If those elements are
|
@@ -782,5 +832,30 @@ module ActiveRecord
|
|
782
832
|
def inspection_filter
|
783
833
|
self.class.inspection_filter
|
784
834
|
end
|
835
|
+
|
836
|
+
def inspect_with_attributes(attributes_to_list)
|
837
|
+
inspection = if @attributes
|
838
|
+
attributes_to_list.filter_map do |name|
|
839
|
+
name = name.to_s
|
840
|
+
if _has_attribute?(name)
|
841
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
842
|
+
end
|
843
|
+
end.join(", ")
|
844
|
+
else
|
845
|
+
"not initialized"
|
846
|
+
end
|
847
|
+
|
848
|
+
"#<#{self.class} #{inspection}>"
|
849
|
+
end
|
850
|
+
|
851
|
+
def attributes_for_inspect
|
852
|
+
self.class.attributes_for_inspect == :all ? all_attributes_for_inspect : self.class.attributes_for_inspect
|
853
|
+
end
|
854
|
+
|
855
|
+
def all_attributes_for_inspect
|
856
|
+
return [] unless @attributes
|
857
|
+
|
858
|
+
attribute_names
|
859
|
+
end
|
785
860
|
end
|
786
861
|
end
|