Fix Active Storage behavior on record dup
Prior to this commit, a `dup`ed record and its originating record would share the same `Attached` proxy objects. Those proxy objects, in turn, would point to the same `Attachment` associations, causing changes made through the proxy interface to affect both records.
This commit is contained in:
parent
803c030144
commit
d02d259b61
|
@ -46,7 +46,8 @@ module ActiveStorage
|
|||
generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
||||
# frozen_string_literal: true
|
||||
def #{name}
|
||||
@active_storage_attached_#{name} ||= ActiveStorage::Attached::One.new("#{name}", self)
|
||||
@active_storage_attached ||= {}
|
||||
@active_storage_attached[:#{name}] ||= ActiveStorage::Attached::One.new("#{name}", self)
|
||||
end
|
||||
|
||||
def #{name}=(attachable)
|
||||
|
@ -116,7 +117,8 @@ module ActiveStorage
|
|||
generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
||||
# frozen_string_literal: true
|
||||
def #{name}
|
||||
@active_storage_attached_#{name} ||= ActiveStorage::Attached::Many.new("#{name}", self)
|
||||
@active_storage_attached ||= {}
|
||||
@active_storage_attached[:#{name}] ||= ActiveStorage::Attached::Many.new("#{name}", self)
|
||||
end
|
||||
|
||||
def #{name}=(attachables)
|
||||
|
@ -183,6 +185,12 @@ module ActiveStorage
|
|||
super || attachment_changes.any?
|
||||
end
|
||||
|
||||
def initialize_dup(*) #:nodoc:
|
||||
super
|
||||
@active_storage_attached = nil
|
||||
@attachment_changes = nil
|
||||
end
|
||||
|
||||
def reload(*) #:nodoc:
|
||||
super.tap { @attachment_changes = nil }
|
||||
end
|
||||
|
|
|
@ -552,6 +552,20 @@ class ActiveStorage::ManyAttachedTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
test "duped record does not share attachments" do
|
||||
@user.highlights.attach [ create_blob(filename: "funky.jpg") ]
|
||||
|
||||
assert_not_equal @user.highlights.first, @user.dup.highlights.first
|
||||
end
|
||||
|
||||
test "duped record does not share attachment changes" do
|
||||
@user.highlights.attach [ create_blob(filename: "funky.jpg") ]
|
||||
assert_not_predicate @user, :changed_for_autosave?
|
||||
|
||||
@user.dup.highlights.attach [ create_blob(filename: "town.mp4") ]
|
||||
assert_not_predicate @user, :changed_for_autosave?
|
||||
end
|
||||
|
||||
test "clearing change on reload" do
|
||||
@user.highlights = [ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ]
|
||||
assert @user.highlights.attached?
|
||||
|
|
|
@ -529,6 +529,20 @@ class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
test "duped record does not share attachments" do
|
||||
@user.avatar.attach create_blob(filename: "funky.jpg")
|
||||
|
||||
assert_not_equal @user.avatar.attachment, @user.dup.avatar.attachment
|
||||
end
|
||||
|
||||
test "duped record does not share attachment changes" do
|
||||
@user.avatar.attach create_blob(filename: "funky.jpg")
|
||||
assert_not_predicate @user, :changed_for_autosave?
|
||||
|
||||
@user.dup.avatar.attach create_blob(filename: "town.jpg")
|
||||
assert_not_predicate @user, :changed_for_autosave?
|
||||
end
|
||||
|
||||
test "clearing change on reload" do
|
||||
@user.avatar = create_blob(filename: "funky.jpg")
|
||||
assert @user.avatar.attached?
|
||||
|
|
Loading…
Reference in New Issue