Project

General

Profile

Defect #38966 » 38966-v3.patch

Go MAEDA, 2024-10-22 11:59

View differences:

db/migrate/20241022095140_remove_orphaned_custom_value_attachments.rb
1
class RemoveOrphanedCustomValueAttachments < ActiveRecord::Migration[7.2]
2
  def up
3
    Attachment.where(container_type: 'CustomValue')
4
              .where('NOT EXISTS (SELECT 1 FROM custom_values WHERE custom_values.id = attachments.container_id)')
5
              .destroy_all
6
  end
7

  
8
  def down
9
    # no-op
10
  end
11
end
lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb
29 29
          return if self.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
30 30
          cattr_accessor :customizable_options
31 31
          self.customizable_options = options
32
          before_destroy :store_attachment_custom_value_ids
32 33
          has_many :custom_values, lambda {includes(:custom_field)},
33 34
                                   :as => :customized,
34 35
                                   :inverse_of => :customized,
......
38 39
          send :include, Redmine::Acts::Customizable::InstanceMethods
39 40
          validate :validate_custom_field_values
40 41
          after_save :save_custom_field_values
42
          after_destroy :destroy_custom_value_attachments
41 43
        end
42 44
      end
43 45

  
......
170 172
          super
171 173
        end
172 174

  
175
        def store_attachment_custom_value_ids
176
          @attachment_custom_value_ids =
177
            custom_values.select {|cv| cv.custom_field.field_format == 'attachment'}
178
                         .map(&:id)
179
        end
180

  
181
        def destroy_custom_value_attachments
182
          Attachment.where(:container_id => @attachment_custom_value_ids, :container_type => 'CustomValue')
183
                    .destroy_all
184
        end
185

  
173 186
        module ClassMethods
174 187
        end
175 188
      end
test/unit/issue_test.rb
2190 2190
    end
2191 2191
  end
2192 2192

  
2193
  def test_destroy_should_delete_attachments_on_custom_values
2194
    cf = IssueCustomField.create!(:name => 'Attachable field', :field_format => 'attachment', :is_for_all => true, :tracker_ids => [1])
2195
    user = User.find(2)
2196
    issue = Issue.new(:project_id => 1, :tracker_id => 1, :subject => 'test', :author_id => user.id)
2197
    attachment = Attachment.create!(:container => issue,:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => user.id)
2198
    issue.send(
2199
      :safe_attributes=,
2200
      {
2201
        'custom_fields' =>
2202
          [
2203
            {'id' => cf.id.to_s, 'value' => attachment.id.to_s},
2204
          ]
2205
      }, user
2206
    )
2207

  
2208
    assert_difference 'CustomValue.where(:customized_type => "Issue").count', -(issue.custom_values.count) do
2209
      assert_difference 'Attachment.count', -1 do
2210
        issue.destroy
2211
      end
2212
    end
2213
  end
2214

  
2193 2215
  def test_destroying_a_deleted_issue_should_not_raise_an_error
2194 2216
    issue = Issue.find(1)
2195 2217
    Issue.find(1).destroy
(4-4/4)