diff --git a/lib/shrine/attacher.rb b/lib/shrine/attacher.rb index c7e4c143..f9091477 100644 --- a/lib/shrine/attacher.rb +++ b/lib/shrine/attacher.rb @@ -341,6 +341,13 @@ def shrine_class private + # The copy constructor that's called on #dup and #clone + # We need to duplicate the context to prevent it from being shared + def initialize_copy(other) + super + @context = @context.dup + end + # Converts a String or Hash value into an UploadedFile object and ensures # it's uploaded to temporary storage. # diff --git a/test/attacher_test.rb b/test/attacher_test.rb index eff885d3..e7f3bcf6 100644 --- a/test/attacher_test.rb +++ b/test/attacher_test.rb @@ -6,6 +6,13 @@ @shrine = @attacher.shrine_class end + describe '#initialize_copy' do + it 'duplicates the context when duplicating the attacher' do + attacher_copy = @attacher.dup + refute_equal @attacher.context.object_id, attacher_copy.context.object_id + end + end + describe ".from_data" do it "instantiates an attacher from file data" do file = @attacher.upload(fakeio) diff --git a/test/plugin/model_test.rb b/test/plugin/model_test.rb index e33b0f2f..4a446d27 100644 --- a/test/plugin/model_test.rb +++ b/test/plugin/model_test.rb @@ -136,6 +136,7 @@ assert_equal model_copy, model_copy.file_attacher.record assert_equal :file, model_copy.file_attacher.name assert_equal Hash[record: model_copy, name: :file], model_copy.file_attacher.context + assert_equal Hash[record: model, name: :file], model.file_attacher.context assert model_copy.file_attacher.changed? # retains any state end