activerecord 8.0.4.1 → 8.0.5
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 +91 -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/connection_adapters/abstract/connection_pool.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +3 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +36 -31
- data/lib/active_record/connection_adapters/postgresql/column.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/column.rb +8 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +15 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
- data/lib/active_record/future_result.rb +2 -0
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/insert_all.rb +2 -2
- data/lib/active_record/migration/command_recorder.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +1 -1
- data/lib/active_record/relation/predicate_builder/array_handler.rb +3 -1
- data/lib/active_record/relation/where_clause.rb +1 -1
- data/lib/active_record/relation.rb +1 -1
- data/lib/active_record/type/serialized.rb +5 -0
- data/lib/arel/predications.rb +1 -3
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5e7c94135bd121cb5e7f78c4a331b85c6194f8395990d23dd0c61d1b0352580
|
|
4
|
+
data.tar.gz: dfb1e24a973b115712e0fae86eac1ec943ef65f708a5dc9da5c4b3854b6c7ad8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c4422f02e0babd91a13fffb9e4d2fd6d5ea6604a3b6d7d7235ed707ef7c9c4d269e19d769bcb07cf561ab2a89e19f86b25783b6f26829343595ed7f7e9cffac0
|
|
7
|
+
data.tar.gz: c4229cc98bf1e7f86be5bbfb5f6aad339c4c4dbadf645084c7ead5d197bb5237d7dcd19fd404456c983885b813161f5007869c4de9963f1e5c81f4431d9bcf24
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,94 @@
|
|
|
1
|
+
## Rails 8.0.5 (March 24, 2026) ##
|
|
2
|
+
|
|
3
|
+
* Fix `insert_all` and `upsert_all` log message when called on anonymous classes.
|
|
4
|
+
|
|
5
|
+
*Gabriel Sobrinho*
|
|
6
|
+
|
|
7
|
+
* Respect `ActiveRecord::SchemaDumper.ignore_tables` when dumping SQLite virtual tables.
|
|
8
|
+
|
|
9
|
+
*Hans Schnedlitz*
|
|
10
|
+
|
|
11
|
+
* Restore previous instrumenter after `execute_or_skip`
|
|
12
|
+
|
|
13
|
+
`FutureResult#execute_or_skip` replaces the thread's instrumenter with an
|
|
14
|
+
`EventBuffer` to collect events published during async query execution.
|
|
15
|
+
If the global async executor is saturated and the `caller_runs` fallback
|
|
16
|
+
executes the task on the calling thread, we need to make sure the previous
|
|
17
|
+
instrumenter is restored or the stale `EventBuffer` would stay in place and
|
|
18
|
+
permanently swallow all subsequent `sql.active_record` notifications on
|
|
19
|
+
that thread.
|
|
20
|
+
|
|
21
|
+
*Rosa Gutierrez*
|
|
22
|
+
|
|
23
|
+
* Fix Ruby 4.0 delegator warning when calling inspect on ActiveRecord::Type::Serialized.
|
|
24
|
+
|
|
25
|
+
*Hammad Khan*
|
|
26
|
+
|
|
27
|
+
* Fix support for table names containing hyphens.
|
|
28
|
+
|
|
29
|
+
*Evgeniy Demin*
|
|
30
|
+
|
|
31
|
+
* Fix column deduplication for SQLite3 and PostgreSQL virtual (generated) columns.
|
|
32
|
+
|
|
33
|
+
`Column#==` and `Column#hash` now account for `virtual?` so that the
|
|
34
|
+
`Deduplicable` registry does not treat a generated column and a regular
|
|
35
|
+
column with the same name and type as identical. Previously, if a
|
|
36
|
+
generated column was registered first, a regular column on a different
|
|
37
|
+
table could be deduplicated to the generated instance, silently
|
|
38
|
+
excluding it from INSERT/UPDATE statements.
|
|
39
|
+
|
|
40
|
+
*Jay Huber*
|
|
41
|
+
|
|
42
|
+
* Fix merging relations with arel equality predicates with null relations.
|
|
43
|
+
|
|
44
|
+
*fatkodima*
|
|
45
|
+
|
|
46
|
+
* Fix SQLite3 schema dump for non-autoincrement integer primary keys.
|
|
47
|
+
|
|
48
|
+
Previously, `schema.rb` should incorrectly restore that table with an auto incrementing
|
|
49
|
+
primary key.
|
|
50
|
+
|
|
51
|
+
*Chris Hasiński*
|
|
52
|
+
|
|
53
|
+
* Fix PostgreSQL `schema_search_path` not being reapplied after `reset!` or `reconnect!`.
|
|
54
|
+
|
|
55
|
+
The `schema_search_path` configured in `database.yml` is now correctly
|
|
56
|
+
reapplied instead of falling back to PostgreSQL defaults.
|
|
57
|
+
|
|
58
|
+
*Tobias Egli*
|
|
59
|
+
|
|
60
|
+
* Ensure batched preloaded associations accounts for klass when grouping to avoid issues with STI.
|
|
61
|
+
|
|
62
|
+
*zzak*, *Stjepan Hadjic*
|
|
63
|
+
|
|
64
|
+
* Fix `ActiveRecord::SoleRecordExceeded#record` to return the relation.
|
|
65
|
+
|
|
66
|
+
This was the case until Rails 7.2, but starting from 8.0 it
|
|
67
|
+
started mistakenly returning the model class.
|
|
68
|
+
|
|
69
|
+
*Jean Boussier*
|
|
70
|
+
|
|
71
|
+
* Improve PostgreSQLAdapter resilience to Timeout.timeout.
|
|
72
|
+
|
|
73
|
+
Better handle asynchronous exceptions being thrown inside
|
|
74
|
+
the `reconnect!` method.
|
|
75
|
+
|
|
76
|
+
This may fixes some deep errors such as:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
undefined method `key?' for nil:NilClass (NoMethodError)
|
|
80
|
+
if !type_map.key?(oid)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
*Jean Boussier*
|
|
84
|
+
|
|
85
|
+
* Fix `eager_load` when loading `has_many` assocations with composite primary keys.
|
|
86
|
+
|
|
87
|
+
This would result in some records being loaded multiple times.
|
|
88
|
+
|
|
89
|
+
*Martin-Alexander*
|
|
90
|
+
|
|
91
|
+
|
|
1
92
|
## Rails 8.0.4.1 (March 23, 2026) ##
|
|
2
93
|
|
|
3
94
|
* 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
|
|
@@ -120,7 +120,7 @@ module ActiveRecord
|
|
|
120
120
|
class ConnectionPool
|
|
121
121
|
# Prior to 3.3.5, WeakKeyMap had a use after free bug
|
|
122
122
|
# https://bugs.ruby-lang.org/issues/20688
|
|
123
|
-
if ObjectSpace.const_defined?(:WeakKeyMap) && RUBY_VERSION >= "3.3.5"
|
|
123
|
+
if ObjectSpace.const_defined?(:WeakKeyMap) && Gem::Version.new(RUBY_VERSION) >= "3.3.5"
|
|
124
124
|
WeakThreadKeyMap = ObjectSpace::WeakKeyMap
|
|
125
125
|
else
|
|
126
126
|
class WeakThreadKeyMap # :nodoc:
|
|
@@ -463,7 +463,7 @@ module ActiveRecord
|
|
|
463
463
|
end
|
|
464
464
|
conn.disconnect!
|
|
465
465
|
end
|
|
466
|
-
@connections = []
|
|
466
|
+
@connections = @pinned_connection ? [@pinned_connection] : []
|
|
467
467
|
@leases.clear
|
|
468
468
|
@available.clear
|
|
469
469
|
end
|
|
@@ -738,7 +738,7 @@ module ActiveRecord
|
|
|
738
738
|
end
|
|
739
739
|
|
|
740
740
|
def extract_table_ref_from_insert_sql(sql)
|
|
741
|
-
if sql =~ /into\s("[A-Za-z0-9_."\[\]\s]+"|[A-Za-z0-9_."\[\]]+)\s*/im
|
|
741
|
+
if sql =~ /into\s("[-A-Za-z0-9_."\[\]\s]+"|[A-Za-z0-9_."\[\]]+)\s*/im
|
|
742
742
|
$1.delete('"').strip
|
|
743
743
|
end
|
|
744
744
|
end
|
|
@@ -1560,11 +1560,11 @@ module ActiveRecord
|
|
|
1560
1560
|
non_combinable_operations = []
|
|
1561
1561
|
|
|
1562
1562
|
operations.each do |command, args|
|
|
1563
|
-
|
|
1563
|
+
args.shift # remove table_name
|
|
1564
1564
|
method = :"#{command}_for_alter"
|
|
1565
1565
|
|
|
1566
1566
|
if respond_to?(method, true)
|
|
1567
|
-
sqls, procs = Array(send(method,
|
|
1567
|
+
sqls, procs = Array(send(method, table_name, *args)).partition { |v| v.is_a?(String) }
|
|
1568
1568
|
sql_fragments.concat(sqls)
|
|
1569
1569
|
non_combinable_operations.concat(procs)
|
|
1570
1570
|
else
|
|
@@ -1572,7 +1572,7 @@ module ActiveRecord
|
|
|
1572
1572
|
non_combinable_operations.each(&:call)
|
|
1573
1573
|
sql_fragments = []
|
|
1574
1574
|
non_combinable_operations = []
|
|
1575
|
-
send(command,
|
|
1575
|
+
send(command, table_name, *args)
|
|
1576
1576
|
end
|
|
1577
1577
|
end
|
|
1578
1578
|
|
|
@@ -666,34 +666,33 @@ module ActiveRecord
|
|
|
666
666
|
deadline = retry_deadline && Process.clock_gettime(Process::CLOCK_MONOTONIC) + retry_deadline
|
|
667
667
|
|
|
668
668
|
@lock.synchronize do
|
|
669
|
-
|
|
669
|
+
attempt_configure_connection do
|
|
670
|
+
reconnect
|
|
670
671
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
672
|
+
enable_lazy_transactions!
|
|
673
|
+
@raw_connection_dirty = false
|
|
674
|
+
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
675
|
+
@verified = true
|
|
675
676
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
677
|
+
reset_transaction(restore: restore_transactions) do
|
|
678
|
+
clear_cache!(new_connection: true)
|
|
679
|
+
configure_connection
|
|
680
|
+
end
|
|
681
|
+
rescue => original_exception
|
|
682
|
+
translated_exception = translate_exception_class(original_exception, nil, nil)
|
|
683
|
+
retry_deadline_exceeded = deadline && deadline < Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
683
684
|
|
|
684
|
-
|
|
685
|
-
|
|
685
|
+
if !retry_deadline_exceeded && retries_available > 0
|
|
686
|
+
retries_available -= 1
|
|
686
687
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
688
|
+
if retryable_connection_error?(translated_exception)
|
|
689
|
+
backoff(connection_retries - retries_available)
|
|
690
|
+
retry
|
|
691
|
+
end
|
|
690
692
|
end
|
|
691
|
-
end
|
|
692
|
-
|
|
693
|
-
@last_activity = nil
|
|
694
|
-
@verified = false
|
|
695
693
|
|
|
696
|
-
|
|
694
|
+
raise translated_exception
|
|
695
|
+
end
|
|
697
696
|
end
|
|
698
697
|
end
|
|
699
698
|
|
|
@@ -701,6 +700,8 @@ module ActiveRecord
|
|
|
701
700
|
# method does nothing.
|
|
702
701
|
def disconnect!
|
|
703
702
|
@lock.synchronize do
|
|
703
|
+
@last_activity = nil
|
|
704
|
+
@verified = false
|
|
704
705
|
clear_cache!(new_connection: true)
|
|
705
706
|
reset_transaction
|
|
706
707
|
@raw_connection_dirty = false
|
|
@@ -726,9 +727,11 @@ module ActiveRecord
|
|
|
726
727
|
# should call super immediately after resetting the connection (and while
|
|
727
728
|
# still holding @lock).
|
|
728
729
|
def reset!
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
730
|
+
attempt_configure_connection do
|
|
731
|
+
clear_cache!(new_connection: true)
|
|
732
|
+
reset_transaction
|
|
733
|
+
configure_connection
|
|
734
|
+
end
|
|
732
735
|
end
|
|
733
736
|
|
|
734
737
|
# Removes the connection from the pool and disconnect it.
|
|
@@ -762,11 +765,13 @@ module ActiveRecord
|
|
|
762
765
|
unless active?
|
|
763
766
|
@lock.synchronize do
|
|
764
767
|
if @unconfigured_connection
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
768
|
+
attempt_configure_connection do
|
|
769
|
+
@raw_connection = @unconfigured_connection
|
|
770
|
+
@unconfigured_connection = nil
|
|
771
|
+
configure_connection
|
|
772
|
+
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
773
|
+
@verified = true
|
|
774
|
+
end
|
|
770
775
|
return
|
|
771
776
|
end
|
|
772
777
|
|
|
@@ -1216,7 +1221,7 @@ module ActiveRecord
|
|
|
1216
1221
|
end
|
|
1217
1222
|
|
|
1218
1223
|
def attempt_configure_connection
|
|
1219
|
-
|
|
1224
|
+
yield
|
|
1220
1225
|
rescue Exception # Need to handle things such as Timeout::ExitException
|
|
1221
1226
|
disconnect!
|
|
1222
1227
|
raise
|
|
@@ -65,7 +65,8 @@ module ActiveRecord
|
|
|
65
65
|
other.is_a?(Column) &&
|
|
66
66
|
super &&
|
|
67
67
|
identity? == other.identity? &&
|
|
68
|
-
serial? == other.serial?
|
|
68
|
+
serial? == other.serial? &&
|
|
69
|
+
virtual? == other.virtual?
|
|
69
70
|
end
|
|
70
71
|
alias :eql? :==
|
|
71
72
|
|
|
@@ -73,7 +74,8 @@ module ActiveRecord
|
|
|
73
74
|
Column.hash ^
|
|
74
75
|
super.hash ^
|
|
75
76
|
identity?.hash ^
|
|
76
|
-
serial?.hash
|
|
77
|
+
serial?.hash ^
|
|
78
|
+
virtual?.hash
|
|
77
79
|
end
|
|
78
80
|
end
|
|
79
81
|
end
|
|
@@ -381,6 +381,11 @@ module ActiveRecord
|
|
|
381
381
|
end
|
|
382
382
|
end
|
|
383
383
|
|
|
384
|
+
def clear_cache!(new_connection: false)
|
|
385
|
+
super
|
|
386
|
+
@schema_search_path = nil if new_connection
|
|
387
|
+
end
|
|
388
|
+
|
|
384
389
|
# Disconnects from the database if already connected. Otherwise, this
|
|
385
390
|
# method does nothing.
|
|
386
391
|
def disconnect!
|
|
@@ -993,6 +998,8 @@ module ActiveRecord
|
|
|
993
998
|
add_pg_encoders
|
|
994
999
|
add_pg_decoders
|
|
995
1000
|
|
|
1001
|
+
schema_search_path # populate cache
|
|
1002
|
+
|
|
996
1003
|
reload_type_map
|
|
997
1004
|
end
|
|
998
1005
|
|
|
@@ -46,7 +46,9 @@ module ActiveRecord
|
|
|
46
46
|
def ==(other)
|
|
47
47
|
other.is_a?(Column) &&
|
|
48
48
|
super &&
|
|
49
|
-
auto_increment? == other.auto_increment?
|
|
49
|
+
auto_increment? == other.auto_increment? &&
|
|
50
|
+
rowid == other.rowid &&
|
|
51
|
+
generated_type == other.generated_type
|
|
50
52
|
end
|
|
51
53
|
alias :eql? :==
|
|
52
54
|
|
|
@@ -54,8 +56,12 @@ module ActiveRecord
|
|
|
54
56
|
Column.hash ^
|
|
55
57
|
super.hash ^
|
|
56
58
|
auto_increment?.hash ^
|
|
57
|
-
rowid.hash
|
|
59
|
+
rowid.hash ^
|
|
60
|
+
virtual?.hash
|
|
58
61
|
end
|
|
62
|
+
|
|
63
|
+
protected
|
|
64
|
+
attr_reader :generated_type
|
|
59
65
|
end
|
|
60
66
|
end
|
|
61
67
|
end
|
|
@@ -6,7 +6,7 @@ module ActiveRecord
|
|
|
6
6
|
class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
|
|
7
7
|
private
|
|
8
8
|
def virtual_tables(stream)
|
|
9
|
-
virtual_tables = @connection.virtual_tables
|
|
9
|
+
virtual_tables = @connection.virtual_tables.reject { |name, _| ignored?(name) }
|
|
10
10
|
if virtual_tables.any?
|
|
11
11
|
stream.puts
|
|
12
12
|
stream.puts " # Virtual tables defined in this database."
|
|
@@ -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)
|
|
@@ -291,7 +291,7 @@ module ActiveRecord
|
|
|
291
291
|
exec_query "DROP INDEX #{quote_column_name(index_name)}"
|
|
292
292
|
end
|
|
293
293
|
|
|
294
|
-
VIRTUAL_TABLE_REGEX = /USING\s+(\w+)\s*\((
|
|
294
|
+
VIRTUAL_TABLE_REGEX = /USING\s+(\w+)\s*\((.*)\)/i
|
|
295
295
|
|
|
296
296
|
# Returns a list of defined virtual tables
|
|
297
297
|
def virtual_tables
|
|
@@ -105,6 +105,7 @@ module ActiveRecord
|
|
|
105
105
|
|
|
106
106
|
@pool.with_connection do |connection|
|
|
107
107
|
return unless @mutex.try_lock
|
|
108
|
+
previous_instrumenter = ActiveSupport::IsolatedExecutionState[:active_record_instrumenter]
|
|
108
109
|
begin
|
|
109
110
|
if pending?
|
|
110
111
|
@event_buffer = EventBuffer.new(self, @instrumenter)
|
|
@@ -113,6 +114,7 @@ module ActiveRecord
|
|
|
113
114
|
execute_query(connection, async: true)
|
|
114
115
|
end
|
|
115
116
|
ensure
|
|
117
|
+
ActiveSupport::IsolatedExecutionState[:active_record_instrumenter] = previous_instrumenter
|
|
116
118
|
@mutex.unlock
|
|
117
119
|
end
|
|
118
120
|
end
|
|
@@ -39,7 +39,7 @@ module ActiveRecord
|
|
|
39
39
|
@returning = (connection.supports_insert_returning? ? primary_keys : false) if @returning.nil?
|
|
40
40
|
@returning = false if @returning == []
|
|
41
41
|
|
|
42
|
-
@unique_by = find_unique_index_for(@unique_by)
|
|
42
|
+
@unique_by = find_unique_index_for(@unique_by) if @on_duplicate != :raise
|
|
43
43
|
|
|
44
44
|
configure_on_duplicate_update_logic
|
|
45
45
|
ensure_valid_options_for_connection!
|
|
@@ -48,7 +48,7 @@ module ActiveRecord
|
|
|
48
48
|
def execute
|
|
49
49
|
return ActiveRecord::Result.empty if inserts.empty?
|
|
50
50
|
|
|
51
|
-
message = +"#{model} "
|
|
51
|
+
message = +"#{model.name} "
|
|
52
52
|
message << "Bulk " if inserts.many?
|
|
53
53
|
message << (on_duplicate == :update ? "Upsert" : "Insert")
|
|
54
54
|
connection.exec_insert_all to_sql, message
|
|
@@ -139,7 +139,7 @@ module ActiveRecord
|
|
|
139
139
|
recorder.reverting = @reverting
|
|
140
140
|
yield recorder.delegate.update_table_definition(table_name, recorder)
|
|
141
141
|
commands = recorder.commands
|
|
142
|
-
@commands << [:change_table, [table_name], -> t { bulk_change_table(
|
|
142
|
+
@commands << [:change_table, [table_name], -> t { bulk_change_table(t.name, commands.reverse) }]
|
|
143
143
|
else
|
|
144
144
|
yield delegate.update_table_definition(table_name, self)
|
|
145
145
|
end
|
|
@@ -31,7 +31,9 @@ module ActiveRecord
|
|
|
31
31
|
values_predicate
|
|
32
32
|
else
|
|
33
33
|
array_predicates = ranges.map! { |range| predicate_builder.build(attribute, range) }
|
|
34
|
-
|
|
34
|
+
values_predicate.or(
|
|
35
|
+
Arel::Nodes::Grouping.new Arel::Nodes::Or.new(array_predicates)
|
|
36
|
+
)
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
@@ -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)
|
|
@@ -1010,7 +1010,7 @@ module ActiveRecord
|
|
|
1010
1010
|
#
|
|
1011
1011
|
# Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
|
|
1012
1012
|
#
|
|
1013
|
-
#
|
|
1013
|
+
# This call deletes the affected posts all at once with a single DELETE statement.
|
|
1014
1014
|
# If you need to destroy dependent associations or call your <tt>before_*</tt> or
|
|
1015
1015
|
# +after_destroy+ callbacks, use the #destroy_all method instead.
|
|
1016
1016
|
#
|
|
@@ -58,6 +58,11 @@ module ActiveRecord
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
private
|
|
61
|
+
# Prevent Ruby 4.0 "delegator does not forward private method" warning.
|
|
62
|
+
# Kernel#inspect calls instance_variables_to_inspect which, without this,
|
|
63
|
+
# triggers Delegator#respond_to_missing? for a private method.
|
|
64
|
+
define_method(:instance_variables_to_inspect, Kernel.instance_method(:instance_variables))
|
|
65
|
+
|
|
61
66
|
def default_value?(value)
|
|
62
67
|
value == coder.load(nil)
|
|
63
68
|
end
|
data/lib/arel/predications.rb
CHANGED
|
@@ -231,9 +231,7 @@ module Arel # :nodoc: all
|
|
|
231
231
|
private
|
|
232
232
|
def grouping_any(method_id, others, *extras)
|
|
233
233
|
nodes = others.map { |expr| send(method_id, expr, *extras) }
|
|
234
|
-
Nodes::Grouping.new nodes
|
|
235
|
-
Nodes::Or.new([memo, node])
|
|
236
|
-
}
|
|
234
|
+
Nodes::Grouping.new Nodes::Or.new(nodes)
|
|
237
235
|
end
|
|
238
236
|
|
|
239
237
|
def grouping_all(method_id, others, *extras)
|
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.0.
|
|
4
|
+
version: 8.0.5
|
|
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.0.
|
|
18
|
+
version: 8.0.5
|
|
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.0.
|
|
25
|
+
version: 8.0.5
|
|
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.0.
|
|
32
|
+
version: 8.0.5
|
|
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.0.
|
|
39
|
+
version: 8.0.5
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: timeout
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -474,10 +474,10 @@ licenses:
|
|
|
474
474
|
- MIT
|
|
475
475
|
metadata:
|
|
476
476
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
|
477
|
-
changelog_uri: https://github.com/rails/rails/blob/v8.0.
|
|
478
|
-
documentation_uri: https://api.rubyonrails.org/v8.0.
|
|
477
|
+
changelog_uri: https://github.com/rails/rails/blob/v8.0.5/activerecord/CHANGELOG.md
|
|
478
|
+
documentation_uri: https://api.rubyonrails.org/v8.0.5/
|
|
479
479
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
|
480
|
-
source_code_uri: https://github.com/rails/rails/tree/v8.0.
|
|
480
|
+
source_code_uri: https://github.com/rails/rails/tree/v8.0.5/activerecord
|
|
481
481
|
rubygems_mfa_required: 'true'
|
|
482
482
|
rdoc_options:
|
|
483
483
|
- "--main"
|