From 7cda4e4889f6355fe80450c5844dc0ef2bf05aa5 Mon Sep 17 00:00:00 2001 From: Nassim Abdelghani Date: Fri, 3 Jan 2025 19:30:33 +0100 Subject: [PATCH] Fix #dup with custom serialisation While `write_uploader` is aliased to `write_attribute` by default, it may be overridden in the model. This change ensures that the override method is called when clearing the attribute. --- lib/carrierwave/orm/activerecord.rb | 2 +- spec/orm/activerecord_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/carrierwave/orm/activerecord.rb b/lib/carrierwave/orm/activerecord.rb index cb247679d..e4e768720 100644 --- a/lib/carrierwave/orm/activerecord.rb +++ b/lib/carrierwave/orm/activerecord.rb @@ -51,7 +51,7 @@ def initialize_dup(other) super @_mounters[:"#{column}"] = nil # The attribute needs to be cleared to prevent it from picked up as identifier - write_attribute(_mounter(:#{column}).serialization_column, nil) + write_uploader(_mounter(:#{column}).serialization_column, nil) _mounter(:"#{column}").cache(old_uploaders) end diff --git a/spec/orm/activerecord_spec.rb b/spec/orm/activerecord_spec.rb index bf10f44aa..c1ebeae80 100644 --- a/spec/orm/activerecord_spec.rb +++ b/spec/orm/activerecord_spec.rb @@ -2181,6 +2181,30 @@ def initialize_dup(*) end end + context 'when #write_uploader is overridden in the model' do + before do + Event.class_eval do + attribute :called_write_uploader_with, :json, default: {} + def write_uploader(*args) + self.called_write_uploader_with[args] ||= 0 + self.called_write_uploader_with[args] += 1 + write_attribute(*args) + end + end + @event = Event.new + end + + it "clears previous attribute value to prevent unintended deduplication" do + @event.image = stub_file('test.jpeg') + @event.save + new_event = @event.dup + new_event.save + + expect(new_event.called_write_uploader_with[[:image, nil].to_s]).to eq 1 + expect(new_event.image.url).to eq '/uploads/test.jpeg' + end + end + context ':mount_on in options' do before { Event.mount_uploader(:image_v2, @uploader, mount_on: :image) } it do