From c6d0aa927021055e5aeec66e6b132e10791fec2e Mon Sep 17 00:00:00 2001 From: Yohta Kimura Date: Tue, 22 Aug 2023 10:35:07 +0900 Subject: [PATCH 1/4] add failing test for https://github.com/carrierwaveuploader/carrierwave/issues/2689 duplication should not affect the duplicated objects path --- spec/orm/activerecord_spec.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/orm/activerecord_spec.rb b/spec/orm/activerecord_spec.rb index 18d8a3957..0dc071049 100644 --- a/spec/orm/activerecord_spec.rb +++ b/spec/orm/activerecord_spec.rb @@ -1991,6 +1991,28 @@ def reload(*) end end + context 'with store_dir using model attributes' do + before do + @uploader.class_eval do + def store_dir + "uploads/#{model.class.name.downcase}/#{mounted_as}/#{model.id}" + end + end + end + + it "wont affect the duplicated object's saved path" do + @event.image = stub_file('test.jpeg') + expect(@event.save).to be_truthy + expect(@event.image.current_path).to eq public_path("uploads/event/image/#{@event.id}/test.jpeg") + new_event = @event.dup + + expect(new_event).not_to be @event + expect(new_event.image.model).to be new_event + expect(@event.save).to be_truthy + expect(@event.image.current_path).to eq public_path("uploads/event/image/#{@event.id}/test.jpeg") + end + end + context 'when #initialize_dup is overridden in the model' do before do Event.class_eval do From 23be183162cb056008ca879946fa0fc87c2f71a7 Mon Sep 17 00:00:00 2001 From: Yohta Kimura Date: Wed, 23 Aug 2023 22:10:24 +0900 Subject: [PATCH 2/4] improve spec --- spec/orm/activerecord_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/orm/activerecord_spec.rb b/spec/orm/activerecord_spec.rb index 0dc071049..eab4d5fd0 100644 --- a/spec/orm/activerecord_spec.rb +++ b/spec/orm/activerecord_spec.rb @@ -2004,10 +2004,12 @@ def store_dir @event.image = stub_file('test.jpeg') expect(@event.save).to be_truthy expect(@event.image.current_path).to eq public_path("uploads/event/image/#{@event.id}/test.jpeg") - new_event = @event.dup + new_event = @event.dup expect(new_event).not_to be @event expect(new_event.image.model).to be new_event + expect(@event.image.current_path).to eq public_path("uploads/event/image/#{@event.id}/test.jpeg") + expect(@event.save).to be_truthy expect(@event.image.current_path).to eq public_path("uploads/event/image/#{@event.id}/test.jpeg") end From c35f486dfb167b172ab2dce6c7de4767581e7711 Mon Sep 17 00:00:00 2001 From: Yohta Kimura Date: Wed, 23 Aug 2023 22:10:31 +0900 Subject: [PATCH 3/4] fix to dup @_mounters cache, because Object#dup wont duplicate @_mounters see https://docs.ruby-lang.org/en/3.1/Object.html#method-i-dup --- lib/carrierwave/orm/activerecord.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/carrierwave/orm/activerecord.rb b/lib/carrierwave/orm/activerecord.rb index a351b1800..cf7b3dec0 100644 --- a/lib/carrierwave/orm/activerecord.rb +++ b/lib/carrierwave/orm/activerecord.rb @@ -43,6 +43,7 @@ def reload(*) # Reset cached mounter on record dup def initialize_dup(other) old_uploaders = _mounter(:"#{column}").uploaders + @_mounters = @_mounters.dup @_mounters[:"#{column}"] = nil super # The attribute needs to be cleared to prevent it from picked up as identifier From e53c9c33674289ffabd8aa6ab3160e2ce60872dd Mon Sep 17 00:00:00 2001 From: Yohta Kimura Date: Sun, 27 Aug 2023 20:37:42 +0900 Subject: [PATCH 4/4] fix to dup mounters cache on mount --- lib/carrierwave/mount.rb | 5 +++++ lib/carrierwave/orm/activerecord.rb | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/carrierwave/mount.rb b/lib/carrierwave/mount.rb index 59ab7ca6d..0b437480d 100644 --- a/lib/carrierwave/mount.rb +++ b/lib/carrierwave/mount.rb @@ -428,6 +428,11 @@ def write_uploader(column, identifier); end private + def initialize_dup(other) + @_mounters = @_mounters.dup + super + end + def _mounter(column) # We cannot memoize in frozen objects :( return Mounter.build(self, column) if frozen? diff --git a/lib/carrierwave/orm/activerecord.rb b/lib/carrierwave/orm/activerecord.rb index cf7b3dec0..a351b1800 100644 --- a/lib/carrierwave/orm/activerecord.rb +++ b/lib/carrierwave/orm/activerecord.rb @@ -43,7 +43,6 @@ def reload(*) # Reset cached mounter on record dup def initialize_dup(other) old_uploaders = _mounter(:"#{column}").uploaders - @_mounters = @_mounters.dup @_mounters[:"#{column}"] = nil super # The attribute needs to be cleared to prevent it from picked up as identifier