activerecord 8.1.1 → 8.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 +70 -0
- data/lib/active_record/associations/join_dependency.rb +2 -2
- data/lib/active_record/associations/preloader/batch.rb +7 -1
- data/lib/active_record/associations.rb +2 -2
- data/lib/active_record/base.rb +1 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +40 -35
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +14 -2
- data/lib/active_record/enum.rb +2 -2
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +1 -1
- data/lib/active_record/relation.rb +1 -1
- data/lib/active_record/runtime_registry.rb +1 -0
- data/lib/active_record/schema_dumper.rb +2 -2
- metadata +9 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 74f90753b3b77d22a985336d06901c0876965ae29376b3a6f0aa0ab2cff9a0e0
|
|
4
|
+
data.tar.gz: 8fd109977d7e47cd685e2b236b7bb4acd891e74e1a878e55b51cbabd436dda45
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 35a0e941325f4dea1f08370e583190628484f2e364285af6fd68179094cfab455e08e0bd3e34f94f102778a19377fcdc368a86c365b8e1cf7c0cbd1e303241d9
|
|
7
|
+
data.tar.gz: '0493ea886af6d96eaeadc88fa06d682597a3019b71fe9d3f13549761959c2f8e5a78921d4ef0ace1daf2b3005e14f95fd99dbd821ed67bac43aa634a99cb7540'
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,73 @@
|
|
|
1
|
+
## Rails 8.1.2 (January 08, 2026) ##
|
|
2
|
+
|
|
3
|
+
* Fix counting cached queries in `ActiveRecord::RuntimeRegistry`.
|
|
4
|
+
|
|
5
|
+
*fatkodima*
|
|
6
|
+
|
|
7
|
+
* Fix merging relations with arel equality predicates with null relations.
|
|
8
|
+
|
|
9
|
+
*fatkodima*
|
|
10
|
+
|
|
11
|
+
* Fix SQLite3 schema dump for non-autoincrement integer primary keys.
|
|
12
|
+
|
|
13
|
+
Previously, `schema.rb` should incorrectly restore that table with an auto incrementing
|
|
14
|
+
primary key.
|
|
15
|
+
|
|
16
|
+
*Chris Hasiński*
|
|
17
|
+
|
|
18
|
+
* Fix PostgreSQL `schema_search_path` not being reapplied after `reset!` or `reconnect!`.
|
|
19
|
+
|
|
20
|
+
The `schema_search_path` configured in `database.yml` is now correctly
|
|
21
|
+
reapplied instead of falling back to PostgreSQL defaults.
|
|
22
|
+
|
|
23
|
+
*Tobias Egli*
|
|
24
|
+
|
|
25
|
+
* Restore the ability of enum to be foats.
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
enum :rating, { low: 0.0, medium: 0.5, high: 1.0 },
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
In Rails 8.1.0, enum values are eagerly validated, and floats weren't expected.
|
|
32
|
+
|
|
33
|
+
*Said Kaldybaev*
|
|
34
|
+
|
|
35
|
+
* Ensure batched preloaded associations accounts for klass when grouping to avoid issues with STI.
|
|
36
|
+
|
|
37
|
+
*zzak*, *Stjepan Hadjic*
|
|
38
|
+
|
|
39
|
+
* Fix `ActiveRecord::SoleRecordExceeded#record` to return the relation.
|
|
40
|
+
|
|
41
|
+
This was the case until Rails 7.2, but starting from 8.0 it
|
|
42
|
+
started mistakenly returning the model class.
|
|
43
|
+
|
|
44
|
+
*Jean Boussier*
|
|
45
|
+
|
|
46
|
+
* Improve PostgreSQLAdapter resilience to Timeout.timeout.
|
|
47
|
+
|
|
48
|
+
Better handle asynchronous exceptions being thrown inside
|
|
49
|
+
the `reconnect!` method.
|
|
50
|
+
|
|
51
|
+
This may fixes some deep errors such as:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
undefined method `key?' for nil:NilClass (NoMethodError)
|
|
55
|
+
if !type_map.key?(oid)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
*Jean Boussier*
|
|
59
|
+
|
|
60
|
+
* Fix structured events for Active Record was not being emitted.
|
|
61
|
+
|
|
62
|
+
*Yuji Yaginuma*
|
|
63
|
+
|
|
64
|
+
* Fix `eager_load` when loading `has_many` assocations with composite primary keys.
|
|
65
|
+
|
|
66
|
+
This would result in some records being loaded multiple times.
|
|
67
|
+
|
|
68
|
+
*Martin-Alexander*
|
|
69
|
+
|
|
70
|
+
|
|
1
71
|
## Rails 8.1.1 (October 28, 2025) ##
|
|
2
72
|
|
|
3
73
|
* No changes.
|
|
@@ -103,7 +103,7 @@ module ActiveRecord
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def instantiate(result_set, strict_loading_value, &block)
|
|
106
|
-
primary_key = aliases.column_alias(join_root,
|
|
106
|
+
primary_key = Array(join_root.primary_key).map { |column| aliases.column_alias(join_root, column) }
|
|
107
107
|
|
|
108
108
|
seen = Hash.new { |i, parent|
|
|
109
109
|
i[parent] = Hash.new { |j, child_class|
|
|
@@ -141,7 +141,7 @@ module ActiveRecord
|
|
|
141
141
|
|
|
142
142
|
message_bus.instrument("instantiation.active_record", payload) do
|
|
143
143
|
result_set.each { |row_hash|
|
|
144
|
-
parent_key = primary_key ? row_hash
|
|
144
|
+
parent_key = primary_key.empty? ? row_hash : row_hash.values_at(*primary_key)
|
|
145
145
|
parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases, column_types, &block)
|
|
146
146
|
construct(parent, join_root, row_hash, seen, model_cache, strict_loading_value)
|
|
147
147
|
}
|
|
@@ -38,7 +38,13 @@ module ActiveRecord
|
|
|
38
38
|
attr_reader :loaders
|
|
39
39
|
|
|
40
40
|
def group_and_load_similar(loaders)
|
|
41
|
-
loaders.grep_v(ThroughAssociation)
|
|
41
|
+
non_through = loaders.grep_v(ThroughAssociation)
|
|
42
|
+
|
|
43
|
+
grouped = non_through.group_by do |loader|
|
|
44
|
+
[loader.loader_query, loader.klass]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
grouped.each do |(query, _klass), similar_loaders|
|
|
42
48
|
query.load_records_in_batch(similar_loaders)
|
|
43
49
|
end
|
|
44
50
|
end
|
|
@@ -1030,9 +1030,9 @@ module ActiveRecord
|
|
|
1030
1030
|
# associated records themselves, you can always do something along the lines of
|
|
1031
1031
|
# <tt>person.tasks.each(&:destroy)</tt>.
|
|
1032
1032
|
#
|
|
1033
|
-
# == Deprecated Associations
|
|
1033
|
+
# == Deprecated \Associations
|
|
1034
1034
|
#
|
|
1035
|
-
# Associations can be marked as deprecated by passing <tt>deprecated: true</tt>:
|
|
1035
|
+
# \Associations can be marked as deprecated by passing <tt>deprecated: true</tt>:
|
|
1036
1036
|
#
|
|
1037
1037
|
# has_many :posts, deprecated: true
|
|
1038
1038
|
#
|
data/lib/active_record/base.rb
CHANGED
|
@@ -6,6 +6,7 @@ require "active_support/descendants_tracker"
|
|
|
6
6
|
require "active_support/time"
|
|
7
7
|
require "active_support/core_ext/class/subclasses"
|
|
8
8
|
require "active_record/log_subscriber"
|
|
9
|
+
require "active_record/structured_event_subscriber"
|
|
9
10
|
require "active_record/relation/delegation"
|
|
10
11
|
require "active_record/attributes"
|
|
11
12
|
require "active_record/type_caster"
|
|
@@ -713,37 +713,36 @@ module ActiveRecord
|
|
|
713
713
|
deadline = retry_deadline && Process.clock_gettime(Process::CLOCK_MONOTONIC) + retry_deadline
|
|
714
714
|
|
|
715
715
|
@lock.synchronize do
|
|
716
|
-
|
|
716
|
+
attempt_configure_connection do
|
|
717
|
+
@allow_preconnect = false
|
|
717
718
|
|
|
718
|
-
|
|
719
|
+
reconnect
|
|
719
720
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
721
|
+
enable_lazy_transactions!
|
|
722
|
+
@raw_connection_dirty = false
|
|
723
|
+
@last_activity = @connected_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
724
|
+
@verified = true
|
|
725
|
+
@allow_preconnect = true
|
|
726
|
+
|
|
727
|
+
reset_transaction(restore: restore_transactions) do
|
|
728
|
+
clear_cache!(new_connection: true)
|
|
729
|
+
configure_connection
|
|
730
|
+
end
|
|
731
|
+
rescue => original_exception
|
|
732
|
+
translated_exception = translate_exception_class(original_exception, nil, nil)
|
|
733
|
+
retry_deadline_exceeded = deadline && deadline < Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
733
734
|
|
|
734
|
-
|
|
735
|
-
|
|
735
|
+
if !retry_deadline_exceeded && retries_available > 0
|
|
736
|
+
retries_available -= 1
|
|
736
737
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
738
|
+
if retryable_connection_error?(translated_exception)
|
|
739
|
+
backoff(connection_retries - retries_available)
|
|
740
|
+
retry
|
|
741
|
+
end
|
|
740
742
|
end
|
|
741
|
-
end
|
|
742
|
-
|
|
743
|
-
@last_activity = nil
|
|
744
|
-
@verified = false
|
|
745
743
|
|
|
746
|
-
|
|
744
|
+
raise translated_exception
|
|
745
|
+
end
|
|
747
746
|
end
|
|
748
747
|
end
|
|
749
748
|
|
|
@@ -755,6 +754,8 @@ module ActiveRecord
|
|
|
755
754
|
reset_transaction
|
|
756
755
|
@raw_connection_dirty = false
|
|
757
756
|
@connected_since = nil
|
|
757
|
+
@last_activity = nil
|
|
758
|
+
@verified = false
|
|
758
759
|
end
|
|
759
760
|
end
|
|
760
761
|
|
|
@@ -777,9 +778,11 @@ module ActiveRecord
|
|
|
777
778
|
# should call super immediately after resetting the connection (and while
|
|
778
779
|
# still holding @lock).
|
|
779
780
|
def reset!
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
781
|
+
attempt_configure_connection do
|
|
782
|
+
clear_cache!(new_connection: true)
|
|
783
|
+
reset_transaction
|
|
784
|
+
configure_connection
|
|
785
|
+
end
|
|
783
786
|
end
|
|
784
787
|
|
|
785
788
|
# Removes the connection from the pool and disconnect it.
|
|
@@ -813,12 +816,14 @@ module ActiveRecord
|
|
|
813
816
|
unless active?
|
|
814
817
|
@lock.synchronize do
|
|
815
818
|
if @unconfigured_connection
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
819
|
+
attempt_configure_connection do
|
|
820
|
+
@raw_connection = @unconfigured_connection
|
|
821
|
+
@unconfigured_connection = nil
|
|
822
|
+
configure_connection
|
|
823
|
+
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
824
|
+
@verified = true
|
|
825
|
+
@allow_preconnect = true
|
|
826
|
+
end
|
|
822
827
|
return
|
|
823
828
|
end
|
|
824
829
|
|
|
@@ -1282,7 +1287,7 @@ module ActiveRecord
|
|
|
1282
1287
|
end
|
|
1283
1288
|
|
|
1284
1289
|
def attempt_configure_connection
|
|
1285
|
-
|
|
1290
|
+
yield
|
|
1286
1291
|
rescue Exception # Need to handle things such as Timeout::ExitException
|
|
1287
1292
|
disconnect!
|
|
1288
1293
|
raise
|
|
@@ -395,6 +395,11 @@ module ActiveRecord
|
|
|
395
395
|
end
|
|
396
396
|
end
|
|
397
397
|
|
|
398
|
+
def clear_cache!(new_connection: false)
|
|
399
|
+
super
|
|
400
|
+
@schema_search_path = nil if new_connection
|
|
401
|
+
end
|
|
402
|
+
|
|
398
403
|
# Disconnects from the database if already connected. Otherwise, this
|
|
399
404
|
# method does nothing.
|
|
400
405
|
def disconnect!
|
|
@@ -1009,6 +1014,8 @@ module ActiveRecord
|
|
|
1009
1014
|
add_pg_encoders
|
|
1010
1015
|
add_pg_decoders
|
|
1011
1016
|
|
|
1017
|
+
schema_search_path # populate cache
|
|
1018
|
+
|
|
1012
1019
|
reload_type_map
|
|
1013
1020
|
end
|
|
1014
1021
|
|
|
@@ -19,11 +19,23 @@ module ActiveRecord
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def default_primary_key?(column)
|
|
22
|
-
schema_type(column) == :integer
|
|
22
|
+
schema_type(column) == :integer && primary_key_has_autoincrement?
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def explicit_primary_key_default?(column)
|
|
26
|
-
column.bigint?
|
|
26
|
+
column.bigint? || (column.type == :integer && !primary_key_has_autoincrement?)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def primary_key_has_autoincrement?
|
|
30
|
+
return false unless table_name
|
|
31
|
+
|
|
32
|
+
table_sql = @connection.query_value(<<~SQL, "SCHEMA")
|
|
33
|
+
SELECT sql FROM sqlite_master WHERE name = #{@connection.quote(table_name)} AND type = 'table'
|
|
34
|
+
UNION ALL
|
|
35
|
+
SELECT sql FROM sqlite_temp_master WHERE name = #{@connection.quote(table_name)} AND type = 'table'
|
|
36
|
+
SQL
|
|
37
|
+
|
|
38
|
+
table_sql.to_s.match?(/\bAUTOINCREMENT\b/i)
|
|
27
39
|
end
|
|
28
40
|
|
|
29
41
|
def prepare_column_options(column)
|
data/lib/active_record/enum.rb
CHANGED
|
@@ -349,10 +349,10 @@ module ActiveRecord
|
|
|
349
349
|
|
|
350
350
|
values.each_value do |value|
|
|
351
351
|
case value
|
|
352
|
-
when String, Integer, true, false, nil
|
|
352
|
+
when String, Integer, Float, true, false, nil
|
|
353
353
|
# noop
|
|
354
354
|
else
|
|
355
|
-
raise ArgumentError, "Enum values #{values} must be only booleans, integers, symbols or strings, got: #{value.class}"
|
|
355
|
+
raise ArgumentError, "Enum values #{values} must be only booleans, integers, floats, symbols or strings, got: #{value.class}"
|
|
356
356
|
end
|
|
357
357
|
end
|
|
358
358
|
|
|
@@ -182,7 +182,7 @@ module ActiveRecord
|
|
|
182
182
|
non_attrs = columns.extract! { |node| node.is_a?(Arel::Predications) }
|
|
183
183
|
|
|
184
184
|
predicates.reject do |node|
|
|
185
|
-
if !non_attrs.empty? && node
|
|
185
|
+
if !non_attrs.empty? && equality_node?(node) && node.left.is_a?(Arel::Predications)
|
|
186
186
|
non_attrs.include?(node.left)
|
|
187
187
|
end || Arel.fetch_attribute(node) do |attr|
|
|
188
188
|
attrs.include?(attr) || columns.include?(attr.name.to_s)
|
|
@@ -1022,7 +1022,7 @@ module ActiveRecord
|
|
|
1022
1022
|
#
|
|
1023
1023
|
# Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
|
|
1024
1024
|
#
|
|
1025
|
-
#
|
|
1025
|
+
# This call deletes the affected posts all at once with a single DELETE statement.
|
|
1026
1026
|
# If you need to destroy dependent associations or call your <tt>before_*</tt> or
|
|
1027
1027
|
# +after_destroy+ callbacks, use the #destroy_all method instead.
|
|
1028
1028
|
#
|
|
@@ -232,8 +232,8 @@ module ActiveRecord
|
|
|
232
232
|
def indexes(table, stream)
|
|
233
233
|
if (indexes = @connection.indexes(table)).any?
|
|
234
234
|
add_index_statements = indexes.map do |index|
|
|
235
|
-
table_name = remove_prefix_and_suffix(index.table)
|
|
236
|
-
" add_index #{([relation_name(table_name)] + index_parts(index)).join(', ')}"
|
|
235
|
+
table_name = remove_prefix_and_suffix(index.table)
|
|
236
|
+
" add_index #{([relation_name(table_name).inspect] + index_parts(index)).join(', ')}"
|
|
237
237
|
end
|
|
238
238
|
|
|
239
239
|
stream.puts add_index_statements.sort.join("\n")
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.1.
|
|
4
|
+
version: 8.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Heinemeier Hansson
|
|
@@ -15,28 +15,28 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 8.1.
|
|
18
|
+
version: 8.1.2
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 8.1.
|
|
25
|
+
version: 8.1.2
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: activemodel
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 8.1.
|
|
32
|
+
version: 8.1.2
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 8.1.
|
|
39
|
+
version: 8.1.2
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: timeout
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -478,10 +478,10 @@ licenses:
|
|
|
478
478
|
- MIT
|
|
479
479
|
metadata:
|
|
480
480
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
|
481
|
-
changelog_uri: https://github.com/rails/rails/blob/v8.1.
|
|
482
|
-
documentation_uri: https://api.rubyonrails.org/v8.1.
|
|
481
|
+
changelog_uri: https://github.com/rails/rails/blob/v8.1.2/activerecord/CHANGELOG.md
|
|
482
|
+
documentation_uri: https://api.rubyonrails.org/v8.1.2/
|
|
483
483
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
|
484
|
-
source_code_uri: https://github.com/rails/rails/tree/v8.1.
|
|
484
|
+
source_code_uri: https://github.com/rails/rails/tree/v8.1.2/activerecord
|
|
485
485
|
rubygems_mfa_required: 'true'
|
|
486
486
|
rdoc_options:
|
|
487
487
|
- "--main"
|
|
@@ -499,7 +499,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
499
499
|
- !ruby/object:Gem::Version
|
|
500
500
|
version: '0'
|
|
501
501
|
requirements: []
|
|
502
|
-
rubygems_version:
|
|
502
|
+
rubygems_version: 4.0.3
|
|
503
503
|
specification_version: 4
|
|
504
504
|
summary: Object-relational mapper framework (part of Rails).
|
|
505
505
|
test_files: []
|