Rails Paperclip how to delete attachment?

后端 未结 6 1055
小鲜肉
小鲜肉 2020-11-30 18:10

I am using Paperclip (w/ Amazon s3) on Rails 3. I want to delete an existing attachment without replacing it using an update action.

I\'ve only foun

相关标签:
6条回答
  • 2020-11-30 18:14

    First off, when you create a check_box in a form_for (which it looks like you are), then the form should by default send :image_delete as "1" if checked and "0" if unchecked. The method declaration looks like this:

    def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
    

    Which shows that you can assign other values if you want to, but that is of course optional.

    Secondly, the call to manually delete an attachment without deleting the model instance to which it is attached to is:

    @page.image.destroy #Will remove the attachment and save the model
    @page.image.clear #Will queue the attachment to be deleted
    

    And to accomplish your way of deleting the images through a checkbox, perhaps add something like this to your Page model:

    class Page < ActiveRecord::Base
      has_attached_file :image
    
      before_save :destroy_image?
    
      def image_delete
        @image_delete ||= "0"
      end
    
      def image_delete=(value)
        @image_delete = value
      end
    
    private
      def destroy_image?
        self.image.clear if @image_delete == "1"
      end
    end
    

    This way, when you create your form and add the :image_delete checkbox, it will load the default value "0" from the User instance. And if that field is checked then the controller will update the image_delete to "1" and when the User is saved, it will check if the image is to be deleted.

    0 讨论(0)
  • 2020-11-30 18:15

    This is Benoit's answer, but wrapped in a module, and covering the edge case of nested attribute models where the destroy tickbox is the only thing changed on the model.

    It will apply to all attachments on the model.

    # This needs to be included after all has_attached_file statements in a class
    module DeletableAttachment
      extend ActiveSupport::Concern
    
      included do
        attachment_definitions.keys.each do |name|
    
          attr_accessor :"delete_#{name}"
    
          before_validation { send(name).clear if send("delete_#{name}") == '1' }
    
          define_method :"delete_#{name}=" do |value|
            instance_variable_set :"@delete_#{name}", value
            send("#{name}_file_name_will_change!")
          end
    
        end
      end
    
    end
    
    0 讨论(0)
  • 2020-11-30 18:18

    has_attached_file :asset

    =>

        attr_accessor :delete_asset
        before_validation { asset.clear if delete_asset == '1' }
    

    No need to destroy asset, Paperclip will do it.

    In the form form.check_box(:delete_asset) will suffice.

    0 讨论(0)
  • 2020-11-30 18:29

    remember to add this to your Page model too:

    attr_accessible :image_delete
    
    0 讨论(0)
  • 2020-11-30 18:32

    Modified version of Paul's solution, to support Rails 5 custom attributes. I just wish there were a way to include the module at the top of the file, before has_attached_file definitions.

    module Mixins
      module PaperclipRemover
    
        extend ActiveSupport::Concern
    
        included do
          attachment_definitions.keys.each do |name|
    
            attribute :"remove_#{name}", :boolean
    
            before_validation do
              self.send("#{name}=", nil) if send("remove_#{name}?")
            end
    
          end
        end
    
      end
    
    end
    
    0 讨论(0)
  • 2020-11-30 18:35

    Was able to achieve this with less code, by just implementing a delete_attachment on the model's side.:

    class MyModel < ApplicationRecord
      has_attached_file :image
    
      def image_delete=(other)
        self.image = nil if other == "1" or other == true
      end
    end
    
    0 讨论(0)
提交回复
热议问题