activerecord 8.0.3 → 8.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a201047b227b7615aae35a9525320e7a9427be7166babc345db794205c0fd1f0
4
- data.tar.gz: d16f7b5c723974f806bedd838e23158930014c605ec466061cc096f212e78c13
3
+ metadata.gz: f3c5a1df42b9008765d10769710e38a21c1a699b11e4ea6d48b7754a74a4fd41
4
+ data.tar.gz: 511579a2cdb39f59d8a5159476e7b8a37b0fc96b93fce1f7971f75244a767bc1
5
5
  SHA512:
6
- metadata.gz: f28650737b1284686b6eefb1396354f4a34d7fb39cf66a969cc1d189dc3f2259cd7f11abda795d8836adf699059a3120f088470a8387d159b89f2a295cfecdaa
7
- data.tar.gz: 803f535ac6e7b962d6433a3e5f1ee58e3e6e1ba452bddfba559ea09f3952c804e3c73a21501da1376b60cdda5af51597e725126108e8c8c5345b25036aecbc20
6
+ metadata.gz: 38bd777e7feaf3eb69d700b4642c317aea2257197c804528473c7c3184b81f0ccd82b327f01c4972dea66f4c1ef0045cb0fd55429d288ed6c5874da6d3151afc
7
+ data.tar.gz: b47c715c3e902c0fa66e9c2cf69b284881db879f1c5defe6b9bbcada477ed3c2a7677fd73ba97b6ff87a3da9e8f6426e9c3374e2f91b9d6c3c47ed78bd3c96e0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,43 @@
1
+ ## Rails 8.0.4 (October 28, 2025) ##
2
+
3
+ * Fix SQLite3 data loss during table alterations with CASCADE foreign keys.
4
+
5
+ When altering a table in SQLite3 that is referenced by child tables with
6
+ `ON DELETE CASCADE` foreign keys, ActiveRecord would silently delete all
7
+ data from the child tables. This occurred because SQLite requires table
8
+ recreation for schema changes, and during this process the original table
9
+ is temporarily dropped, triggering CASCADE deletes on child tables.
10
+
11
+ The root cause was incorrect ordering of operations. The original code
12
+ wrapped `disable_referential_integrity` inside a transaction, but
13
+ `PRAGMA foreign_keys` cannot be modified inside a transaction in SQLite -
14
+ attempting to do so simply has no effect. This meant foreign keys remained
15
+ enabled during table recreation, causing CASCADE deletes to fire.
16
+
17
+ The fix reverses the order to follow the official SQLite 12-step ALTER TABLE
18
+ procedure: `disable_referential_integrity` now wraps the transaction instead
19
+ of being wrapped by it. This ensures foreign keys are properly disabled
20
+ before the transaction starts and re-enabled after it commits, preventing
21
+ CASCADE deletes while maintaining data integrity through atomic transactions.
22
+
23
+ *Ruy Rocha*
24
+
25
+ * Add support for bound SQL literals in CTEs.
26
+
27
+ *Nicolas Bachschmidt*
28
+
29
+ * Fix `belongs_to` associations not to clear the entire composite primary key.
30
+
31
+ When clearing a `belongs_to` association that references a model with composite primary key,
32
+ only the optional part of the key should be cleared.
33
+
34
+ *zzak*
35
+
36
+ * Fix invalid records being autosaved when distantly associated records are marked for deletion.
37
+
38
+ *Ian Terrell*, *axlekb AB*
39
+
40
+
1
41
  ## Rails 8.0.3 (September 22, 2025) ##
2
42
 
3
43
  * Fix query cache for pinned connections in multi threaded transactional tests
@@ -135,7 +135,9 @@ module ActiveRecord
135
135
  target_key_values = record ? Array(primary_key(record.class)).map { |key| record._read_attribute(key) } : []
136
136
 
137
137
  if force || reflection_fk.map { |fk| owner._read_attribute(fk) } != target_key_values
138
+ owner_pk = Array(owner.class.primary_key)
138
139
  reflection_fk.each_with_index do |key, index|
140
+ next if record.nil? && owner_pk.include?(key)
139
141
  owner[key] = target_key_values[index]
140
142
  end
141
143
  end
@@ -374,7 +374,7 @@ module ActiveRecord
374
374
  context = validation_context if custom_validation_context?
375
375
  return true if record.valid?(context)
376
376
 
377
- if record.changed? || record.new_record? || context
377
+ if context || record.changed_for_autosave?
378
378
  associated_errors = record.errors.objects
379
379
  else
380
380
  # If there are existing invalid records in the DB, we should still be able to reference them.
@@ -583,8 +583,8 @@ module ActiveRecord
583
583
  yield definition if block_given?
584
584
  end
585
585
 
586
- transaction do
587
- disable_referential_integrity do
586
+ disable_referential_integrity do
587
+ transaction do
588
588
  move_table(table_name, altered_table_name, options.merge(temporary: true))
589
589
  move_table(altered_table_name, table_name, &caller)
590
590
  end
@@ -172,9 +172,11 @@ module ActiveRecord
172
172
  prevent_writes = true if role == ActiveRecord.reading_role
173
173
 
174
174
  append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: classes)
175
- yield
176
- ensure
177
- connected_to_stack.pop
175
+ begin
176
+ yield
177
+ ensure
178
+ connected_to_stack.pop
179
+ end
178
180
  end
179
181
 
180
182
  # Passes the block to +connected_to+ for every +shard+ the
@@ -395,11 +397,13 @@ module ActiveRecord
395
397
  prevent_writes = true if role == ActiveRecord.reading_role
396
398
 
397
399
  append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: [self])
398
- return_value = yield
399
- return_value.load if return_value.is_a? ActiveRecord::Relation
400
- return_value
401
- ensure
402
- self.connected_to_stack.pop
400
+ begin
401
+ return_value = yield
402
+ return_value.load if return_value.is_a? ActiveRecord::Relation
403
+ return_value
404
+ ensure
405
+ self.connected_to_stack.pop
406
+ end
403
407
  end
404
408
 
405
409
  def append_to_connected_to_stack(entry)
@@ -9,7 +9,7 @@ module ActiveRecord
9
9
  module VERSION
10
10
  MAJOR = 8
11
11
  MINOR = 0
12
- TINY = 3
12
+ TINY = 4
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -1928,7 +1928,8 @@ module ActiveRecord
1928
1928
 
1929
1929
  def build_with_expression_from_value(value, nested = false)
1930
1930
  case value
1931
- when Arel::Nodes::SqlLiteral then Arel::Nodes::Grouping.new(value)
1931
+ when Arel::Nodes::SqlLiteral, Arel::Nodes::BoundSqlLiteral
1932
+ Arel::Nodes::Grouping.new(value)
1932
1933
  when ActiveRecord::Relation
1933
1934
  if nested
1934
1935
  value.arel.ast
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.3
4
+ version: 8.0.4
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.3
18
+ version: 8.0.4
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.3
25
+ version: 8.0.4
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.3
32
+ version: 8.0.4
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.3
39
+ version: 8.0.4
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.3/activerecord/CHANGELOG.md
478
- documentation_uri: https://api.rubyonrails.org/v8.0.3/
477
+ changelog_uri: https://github.com/rails/rails/blob/v8.0.4/activerecord/CHANGELOG.md
478
+ documentation_uri: https://api.rubyonrails.org/v8.0.4/
479
479
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
480
- source_code_uri: https://github.com/rails/rails/tree/v8.0.3/activerecord
480
+ source_code_uri: https://github.com/rails/rails/tree/v8.0.4/activerecord
481
481
  rubygems_mfa_required: 'true'
482
482
  rdoc_options:
483
483
  - "--main"