activerecord 7.1.3 → 7.1.4
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 +266 -0
- data/lib/active_record/associations/belongs_to_association.rb +4 -4
- data/lib/active_record/associations/collection_association.rb +4 -4
- data/lib/active_record/associations/has_many_association.rb +2 -2
- data/lib/active_record/associations/has_one_association.rb +2 -2
- data/lib/active_record/associations/join_dependency.rb +6 -8
- data/lib/active_record/associations.rb +6 -0
- data/lib/active_record/attribute_methods/dirty.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +3 -3
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +46 -6
- data/lib/active_record/autosave_association.rb +5 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +8 -1
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -4
- data/lib/active_record/connection_adapters/abstract_adapter.rb +14 -15
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +37 -13
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +2 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +16 -10
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -2
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +16 -20
- data/lib/active_record/core.rb +7 -2
- data/lib/active_record/counter_cache.rb +7 -3
- data/lib/active_record/database_configurations/hash_config.rb +6 -2
- data/lib/active_record/delegated_type.rb +6 -6
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/encryption/encrypted_attribute_type.rb +2 -2
- data/lib/active_record/encryption/scheme.rb +8 -4
- data/lib/active_record/future_result.rb +9 -0
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/marshalling.rb +1 -1
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/migration/compatibility.rb +6 -0
- data/lib/active_record/model_schema.rb +6 -2
- data/lib/active_record/persistence.rb +2 -2
- data/lib/active_record/query_cache.rb +1 -1
- data/lib/active_record/query_logs_formatter.rb +1 -1
- data/lib/active_record/railtie.rb +10 -13
- data/lib/active_record/railties/databases.rake +2 -2
- data/lib/active_record/reflection.rb +8 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +6 -1
- data/lib/active_record/relation/query_methods.rb +21 -7
- data/lib/active_record/relation.rb +13 -3
- data/lib/active_record/result.rb +1 -1
- data/lib/active_record/tasks/database_tasks.rb +19 -8
- data/lib/active_record/test_fixtures.rb +1 -0
- data/lib/active_record/timestamp.rb +3 -1
- data/lib/active_record.rb +2 -2
- data/lib/arel/tree_manager.rb +5 -1
- data/lib/arel/visitors/to_sql.rb +2 -1
- metadata +10 -10
@@ -146,6 +146,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
146
146
|
config.after_initialize do |app|
|
147
147
|
ActiveSupport.on_load(:active_record) do
|
148
148
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
|
149
|
+
next if db_config.nil?
|
149
150
|
|
150
151
|
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
|
151
152
|
db_config.name,
|
@@ -261,8 +262,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
261
262
|
end
|
262
263
|
|
263
264
|
ActiveSupport.on_load(:active_record) do
|
264
|
-
|
265
|
-
configs = configs.except(
|
265
|
+
configs_used_in_other_initializers = configs.except(
|
266
266
|
:migration_error,
|
267
267
|
:database_selector,
|
268
268
|
:database_resolver,
|
@@ -279,7 +279,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
279
279
|
:use_schema_cache_dump
|
280
280
|
)
|
281
281
|
|
282
|
-
|
282
|
+
configs_used_in_other_initializers.each do |k, v|
|
283
283
|
next if k == :encryption
|
284
284
|
setter = "#{k}="
|
285
285
|
# Some existing initializers might rely on Active Record configuration
|
@@ -377,23 +377,20 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
377
377
|
end
|
378
378
|
|
379
379
|
initializer "active_record_encryption.configuration" do |app|
|
380
|
-
|
381
|
-
|
382
|
-
config.after_initialize do |app|
|
380
|
+
ActiveSupport.on_load(:active_record) do
|
383
381
|
ActiveRecord::Encryption.configure \
|
384
382
|
primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
|
385
383
|
deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
|
386
384
|
key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
|
387
|
-
**config.active_record.encryption
|
385
|
+
**app.config.active_record.encryption
|
388
386
|
|
387
|
+
auto_filtered_parameters = ActiveRecord::Encryption::AutoFilteredParameters.new(app)
|
389
388
|
auto_filtered_parameters.enable if ActiveRecord::Encryption.config.add_to_filter_parameters
|
390
389
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
|
396
|
-
end
|
390
|
+
# Support extended queries for deterministic attributes and validations
|
391
|
+
if ActiveRecord::Encryption.config.extend_queries
|
392
|
+
ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
|
393
|
+
ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
|
397
394
|
end
|
398
395
|
end
|
399
396
|
|
@@ -89,10 +89,10 @@ db_namespace = namespace :db do
|
|
89
89
|
task migrate: :load_config do
|
90
90
|
db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
|
91
91
|
|
92
|
-
if db_configs.size == 1
|
92
|
+
if db_configs.size == 1 && db_configs.first.primary?
|
93
93
|
ActiveRecord::Tasks::DatabaseTasks.migrate
|
94
94
|
else
|
95
|
-
mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
|
95
|
+
mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
|
96
96
|
|
97
97
|
mapped_versions.sort.each do |version, db_configs|
|
98
98
|
db_configs.each do |db_config|
|
@@ -786,7 +786,7 @@ module ActiveRecord
|
|
786
786
|
primary_query_constraints = active_record.query_constraints_list
|
787
787
|
owner_pk = active_record.primary_key
|
788
788
|
|
789
|
-
if primary_query_constraints.size
|
789
|
+
if primary_query_constraints.size > 2
|
790
790
|
raise ArgumentError, <<~MSG.squish
|
791
791
|
The query constraints list on the `#{active_record}` model has more than 2
|
792
792
|
attributes. Active Record is unable to derive the query constraints
|
@@ -804,6 +804,8 @@ module ActiveRecord
|
|
804
804
|
MSG
|
805
805
|
end
|
806
806
|
|
807
|
+
return foreign_key if primary_query_constraints.include?(foreign_key)
|
808
|
+
|
807
809
|
first_key, last_key = primary_query_constraints
|
808
810
|
|
809
811
|
if first_key == owner_pk
|
@@ -869,7 +871,11 @@ module ActiveRecord
|
|
869
871
|
# klass option is necessary to support loading polymorphic associations
|
870
872
|
def association_primary_key(klass = nil)
|
871
873
|
if primary_key = options[:primary_key]
|
872
|
-
@association_primary_key ||=
|
874
|
+
@association_primary_key ||= if primary_key.is_a?(Array)
|
875
|
+
primary_key.map { |pk| pk.to_s.freeze }.freeze
|
876
|
+
else
|
877
|
+
-primary_key.to_s
|
878
|
+
end
|
873
879
|
elsif (klass || self.klass).has_query_constraints? || options[:query_constraints]
|
874
880
|
(klass || self.klass).composite_query_constraints_list
|
875
881
|
elsif (klass || self.klass).composite_primary_key?
|
@@ -43,7 +43,12 @@ module ActiveRecord
|
|
43
43
|
|
44
44
|
def convert_to_id(value)
|
45
45
|
if value.is_a?(Base)
|
46
|
-
|
46
|
+
primary_key = primary_key(value)
|
47
|
+
if primary_key.is_a?(Array)
|
48
|
+
primary_key.map { |column| value._read_attribute(column) }
|
49
|
+
else
|
50
|
+
value._read_attribute(primary_key)
|
51
|
+
end
|
47
52
|
elsif value.is_a?(Relation)
|
48
53
|
value.select(primary_key(value))
|
49
54
|
else
|
@@ -1909,18 +1909,32 @@ module ActiveRecord
|
|
1909
1909
|
end
|
1910
1910
|
|
1911
1911
|
def column_references(order_args)
|
1912
|
-
|
1912
|
+
order_args.flat_map do |arg|
|
1913
1913
|
case arg
|
1914
1914
|
when String, Symbol
|
1915
|
-
arg
|
1915
|
+
extract_table_name_from(arg)
|
1916
1916
|
when Hash
|
1917
|
-
arg
|
1918
|
-
|
1917
|
+
arg
|
1918
|
+
.map do |key, value|
|
1919
|
+
case value
|
1920
|
+
when Hash
|
1921
|
+
key.to_s
|
1922
|
+
else
|
1923
|
+
extract_table_name_from(key) if key.is_a?(String) || key.is_a?(Symbol)
|
1924
|
+
end
|
1925
|
+
end
|
1926
|
+
when Arel::Attribute
|
1927
|
+
arg.relation.name
|
1928
|
+
when Arel::Nodes::Ordering
|
1929
|
+
if arg.expr.is_a?(Arel::Attribute)
|
1930
|
+
arg.expr.relation.name
|
1919
1931
|
end
|
1920
1932
|
end
|
1921
|
-
end
|
1922
|
-
|
1923
|
-
|
1933
|
+
end.compact
|
1934
|
+
end
|
1935
|
+
|
1936
|
+
def extract_table_name_from(string)
|
1937
|
+
string.match(/^\W?(\w+)\W?\./) && $1
|
1924
1938
|
end
|
1925
1939
|
|
1926
1940
|
def order_column(field)
|
@@ -526,7 +526,12 @@ module ActiveRecord
|
|
526
526
|
|
527
527
|
group_values_arel_columns = arel_columns(group_values.uniq)
|
528
528
|
having_clause_ast = having_clause.ast unless having_clause.empty?
|
529
|
-
|
529
|
+
key = if klass.composite_primary_key?
|
530
|
+
primary_key.map { |pk| table[pk] }
|
531
|
+
else
|
532
|
+
table[primary_key]
|
533
|
+
end
|
534
|
+
stmt = arel.compile_update(values, key, having_clause_ast, group_values_arel_columns)
|
530
535
|
klass.connection.update(stmt, "#{klass} Update All").tap { reset }
|
531
536
|
end
|
532
537
|
|
@@ -659,7 +664,12 @@ module ActiveRecord
|
|
659
664
|
|
660
665
|
group_values_arel_columns = arel_columns(group_values.uniq)
|
661
666
|
having_clause_ast = having_clause.ast unless having_clause.empty?
|
662
|
-
|
667
|
+
key = if klass.composite_primary_key?
|
668
|
+
primary_key.map { |pk| table[pk] }
|
669
|
+
else
|
670
|
+
table[primary_key]
|
671
|
+
end
|
672
|
+
stmt = arel.compile_delete(key, having_clause_ast, group_values_arel_columns)
|
663
673
|
|
664
674
|
klass.connection.delete(stmt, "#{klass} Delete All").tap { reset }
|
665
675
|
end
|
@@ -975,7 +985,7 @@ module ActiveRecord
|
|
975
985
|
def exec_main_query(async: false)
|
976
986
|
if @none
|
977
987
|
if async
|
978
|
-
return FutureResult
|
988
|
+
return FutureResult.wrap([])
|
979
989
|
else
|
980
990
|
return []
|
981
991
|
end
|
data/lib/active_record/result.rb
CHANGED
@@ -195,7 +195,7 @@ module ActiveRecord
|
|
195
195
|
EMPTY = new([].freeze, [].freeze, {}.freeze).freeze
|
196
196
|
private_constant :EMPTY
|
197
197
|
|
198
|
-
EMPTY_ASYNC = FutureResult
|
198
|
+
EMPTY_ASYNC = FutureResult.wrap(EMPTY).freeze
|
199
199
|
private_constant :EMPTY_ASYNC
|
200
200
|
end
|
201
201
|
end
|
@@ -192,9 +192,17 @@ module ActiveRecord
|
|
192
192
|
|
193
193
|
seed = true
|
194
194
|
end
|
195
|
+
end
|
196
|
+
end
|
195
197
|
|
196
|
-
|
197
|
-
|
198
|
+
each_current_environment(env) do |environment|
|
199
|
+
db_configs_with_versions(environment).sort.each do |version, db_configs|
|
200
|
+
db_configs.each do |db_config|
|
201
|
+
with_temporary_pool(db_config) do
|
202
|
+
migrate(version)
|
203
|
+
dump_schema(db_config) if ActiveRecord.dump_schema_after_migration
|
204
|
+
end
|
205
|
+
end
|
198
206
|
end
|
199
207
|
end
|
200
208
|
|
@@ -255,10 +263,10 @@ module ActiveRecord
|
|
255
263
|
Migration.verbose = verbose_was
|
256
264
|
end
|
257
265
|
|
258
|
-
def db_configs_with_versions(
|
266
|
+
def db_configs_with_versions(environment = env) # :nodoc:
|
259
267
|
db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
|
260
268
|
|
261
|
-
with_temporary_connection_for_each do |conn|
|
269
|
+
with_temporary_connection_for_each(env: environment) do |conn|
|
262
270
|
db_config = conn.pool.db_config
|
263
271
|
versions_to_run = conn.migration_context.pending_migration_versions
|
264
272
|
target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
|
@@ -552,10 +560,7 @@ module ActiveRecord
|
|
552
560
|
end
|
553
561
|
|
554
562
|
def each_current_configuration(environment, name = nil)
|
555
|
-
|
556
|
-
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
557
|
-
|
558
|
-
environments.each do |env|
|
563
|
+
each_current_environment(environment) do |env|
|
559
564
|
configs_for(env_name: env).each do |db_config|
|
560
565
|
next if name && name != db_config.name
|
561
566
|
|
@@ -564,6 +569,12 @@ module ActiveRecord
|
|
564
569
|
end
|
565
570
|
end
|
566
571
|
|
572
|
+
def each_current_environment(environment, &block)
|
573
|
+
environments = [environment]
|
574
|
+
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
575
|
+
environments.each(&block)
|
576
|
+
end
|
577
|
+
|
567
578
|
def each_local_configuration
|
568
579
|
configs_for.each do |db_config|
|
569
580
|
next unless db_config.database
|
@@ -54,8 +54,10 @@ module ActiveRecord
|
|
54
54
|
|
55
55
|
module ClassMethods # :nodoc:
|
56
56
|
def touch_attributes_with_time(*names, time: nil)
|
57
|
+
names = names.map(&:to_s)
|
58
|
+
names = names.map { |name| attribute_aliases[name] || name }
|
57
59
|
attribute_names = timestamp_attributes_for_update_in_model
|
58
|
-
attribute_names |= names
|
60
|
+
attribute_names |= names
|
59
61
|
attribute_names.index_with(time || current_time_from_proper_timezone)
|
60
62
|
end
|
61
63
|
|
data/lib/active_record.rb
CHANGED
@@ -34,7 +34,7 @@ require "active_record/deprecator"
|
|
34
34
|
require "active_model/attribute_set"
|
35
35
|
require "active_record/errors"
|
36
36
|
|
37
|
-
# :include:
|
37
|
+
# :include: ../README.rdoc
|
38
38
|
module ActiveRecord
|
39
39
|
extend ActiveSupport::Autoload
|
40
40
|
|
@@ -277,7 +277,7 @@ module ActiveRecord
|
|
277
277
|
# with the global thread pool async query executor.
|
278
278
|
def self.global_executor_concurrency=(global_executor_concurrency)
|
279
279
|
if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
|
280
|
-
raise ArgumentError, "`global_executor_concurrency` cannot be set when
|
280
|
+
raise ArgumentError, "`global_executor_concurrency` cannot be set when the executor is nil or set to `:multi_thread_pool`. For multiple thread pools, please set the concurrency in your database configuration."
|
281
281
|
end
|
282
282
|
|
283
283
|
@global_executor_concurrency = global_executor_concurrency
|
data/lib/arel/tree_manager.rb
CHANGED
data/lib/arel/visitors/to_sql.rb
CHANGED
@@ -930,7 +930,8 @@ module Arel # :nodoc: all
|
|
930
930
|
stmt.limit = nil
|
931
931
|
stmt.offset = nil
|
932
932
|
stmt.orders = []
|
933
|
-
|
933
|
+
columns = Arel::Nodes::Grouping.new(o.key)
|
934
|
+
stmt.wheres = [Nodes::In.new(columns, [build_subselect(o.key, o)])]
|
934
935
|
stmt.relation = o.relation.left if has_join_sources?(o)
|
935
936
|
stmt.groups = o.groups unless o.groups.empty?
|
936
937
|
stmt.havings = o.havings unless o.havings.empty?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.1.
|
4
|
+
version: 7.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 7.1.
|
19
|
+
version: 7.1.4
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 7.1.
|
26
|
+
version: 7.1.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 7.1.
|
33
|
+
version: 7.1.4
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 7.1.
|
40
|
+
version: 7.1.4
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: timeout
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -470,10 +470,10 @@ licenses:
|
|
470
470
|
- MIT
|
471
471
|
metadata:
|
472
472
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
473
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.1.
|
474
|
-
documentation_uri: https://api.rubyonrails.org/v7.1.
|
473
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.1.4/activerecord/CHANGELOG.md
|
474
|
+
documentation_uri: https://api.rubyonrails.org/v7.1.4/
|
475
475
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
476
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.1.
|
476
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.1.4/activerecord
|
477
477
|
rubygems_mfa_required: 'true'
|
478
478
|
post_install_message:
|
479
479
|
rdoc_options:
|
@@ -492,7 +492,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
492
492
|
- !ruby/object:Gem::Version
|
493
493
|
version: '0'
|
494
494
|
requirements: []
|
495
|
-
rubygems_version: 3.
|
495
|
+
rubygems_version: 3.5.11
|
496
496
|
signing_key:
|
497
497
|
specification_version: 4
|
498
498
|
summary: Object-relational mapper framework (part of Rails).
|