diff --git a/activestorage/lib/active_storage/attached/model.rb b/activestorage/lib/active_storage/attached/model.rb index 027d52c459..2c600fae01 100644 --- a/activestorage/lib/active_storage/attached/model.rb +++ b/activestorage/lib/active_storage/attached/model.rb @@ -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 diff --git a/activestorage/test/models/attached/many_test.rb b/activestorage/test/models/attached/many_test.rb index 6be89a6afa..62620f9f84 100644 --- a/activestorage/test/models/attached/many_test.rb +++ b/activestorage/test/models/attached/many_test.rb @@ -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? diff --git a/activestorage/test/models/attached/one_test.rb b/activestorage/test/models/attached/one_test.rb index 3d5a7dc360..f3c5ead528 100644 --- a/activestorage/test/models/attached/one_test.rb +++ b/activestorage/test/models/attached/one_test.rb @@ -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?