Skip to content

Commit cfc6c56

Browse files
authored
Merge pull request rails#53623 from Edouard-chin/ec-autosave-blob
Prevent Active Storage Blob from autosaving Attachments:
2 parents db40022 + e70f504 commit cfc6c56

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

activestorage/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1+
* A Blob will no longer autosave associated Attachment.
2+
3+
This fixes an issue where a record with an attachment would have
4+
its dirty attributes reset, preventing your `after commit` callbacks
5+
on that record to behave as expected.
6+
7+
Note that this change doesn't require any changes on your application
8+
and is supposed to be internal. Active Storage Attachment will continue
9+
to be autosaved (through a different relation).
10+
11+
*Edouard-chin*
112

213
Please check [8-0-stable](https://github.com/rails/rails/blob/8-0-stable/activestorage/CHANGELOG.md) for previous changes.

activestorage/app/models/active_storage/blob.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class ActiveStorage::Blob < ActiveStorage::Record
2929
# :method:
3030
#
3131
# Returns the associated ActiveStorage::Attachment instances.
32-
has_many :attachments
32+
has_many :attachments, autosave: false
3333

3434
##
3535
# :singleton-method:

activestorage/test/models/attachment_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,27 @@ class ActiveStorage::AttachmentTest < ActiveSupport::TestCase
3838
assert_predicate blob.reload, :analyzed?
3939
end
4040

41+
test "attaching a blob doesn't touch the record" do
42+
data = "Something else entirely!"
43+
io = StringIO.new(data)
44+
blob = create_blob_before_direct_upload byte_size: data.size, checksum: OpenSSL::Digest::MD5.base64digest(data)
45+
blob.upload(io)
46+
47+
user = User.create!(
48+
name: "Roger",
49+
avatar: blob.signed_id,
50+
record_callbacks: true,
51+
)
52+
53+
assert_equal(1, user.callback_counter)
54+
end
55+
56+
test "attaching a record doesn't reset the previously_new_record flag" do
57+
@user.highlights.attach(io: ::StringIO.new("dummy"), filename: "dummy.txt")
58+
59+
assert(@user.notification_sent)
60+
end
61+
4162
test "mirroring a directly-uploaded blob after attaching it" do
4263
with_service("mirror") do
4364
blob = directly_upload_file_blob

activestorage/test/test_helper.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ def with_raise_on_open_redirects(service)
121121
ActiveRecord::Base.include GlobalID::Identification
122122

123123
class User < ActiveRecord::Base
124+
attr_accessor :record_callbacks, :callback_counter
125+
attr_reader :notification_sent
126+
124127
validates :name, presence: true
125128

126129
has_one_attached :avatar
@@ -161,11 +164,25 @@ class User < ActiveRecord::Base
161164
attachable.variant :preview, resize_to_fill: [400, 400], preprocessed: true
162165
end
163166

167+
after_commit :increment_callback_counter
168+
after_update_commit :notify
169+
164170
accepts_nested_attributes_for :highlights_attachments, allow_destroy: true
165171

166172
def should_preprocessed?
167173
name == "transform via method"
168174
end
175+
176+
def increment_callback_counter
177+
if record_callbacks
178+
@callback_counter ||= 0
179+
@callback_counter += 1
180+
end
181+
end
182+
183+
def notify
184+
@notification_sent = true if highlights_attachments.any?(&:previously_new_record?)
185+
end
169186
end
170187

171188
class Group < ActiveRecord::Base

0 commit comments

Comments
 (0)