Rails Paperclip如何删除附件?

jyo*_*eph 84 ruby ruby-on-rails paperclip

我在Rails 3上使用Paperclip(带有Amazon s3).我想删除现有附件而不使用更新操作替换它.

我只发现了这样的一个实例在这里,不能得到那个工作,它只是不会删除,并没有什么在日志中说为什么.我想在表单上做这样的事情:

<%- unless @page.new_record? || !@page.image? -%>
    <%= f.check_box :image_delete, :label => 'Delete Image' %>
<%- end -%>
Run Code Online (Sandbox Code Playgroud)

(页面是模型的名称,image是保存附件的属性名称)

但是,如何检测该复选框,更重要的是,如何删除图像?我感谢任何帮助!

Dan*_*nne 101

首先,当你在form_for中创建一个check_box时(它看起来像你),那么默认情况下表单应该发送:image_delete如果选中则为"1",如果未选中则返回"0".方法声明如下所示:

def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
Run Code Online (Sandbox Code Playgroud)

这表明您可以根据需要分配其他值,但这当然是可选的.

其次,手动删除附件而不删除附加到的模型实例的调用是:

@page.image.destroy #Will remove the attachment and save the model
@page.image.clear #Will queue the attachment to be deleted
Run Code Online (Sandbox Code Playgroud)

要通过复选框完成删除图像的方式,可能会在页面模型中添加以下内容:

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
Run Code Online (Sandbox Code Playgroud)

这样,当您创建表单并添加:image_delete复选框时,它将从User实例加载默认值"0".如果检查该字段,则控制器将image_delete更新为"1",并且当保存用户时,它将检查是否要删除图像.

  • 这种方法对我也有用......但是我遇到了一个问题......如果用户检查了image_delete复选框并同时在表单中添加了一个新图像,那么旧图像将被删除并且新图像不会被保存.我通过在`destroy_image?`方法中将条件更改为`self.image.clear if @image_delete =="1"和!image.dirty?`来解决这个问题 (10认同)

Ben*_* B. 96

has_attached_file :asset

=>

    attr_accessor :delete_asset
    before_validation { asset.clear if delete_asset == '1' }
Run Code Online (Sandbox Code Playgroud)

没有必要破坏资产,Paperclip会这样做.

在表格中form.check_box(:delete_asset)就足够了.

  • @SurgePedroza我相信您需要允许参数:delete_asset,请参阅http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters (4认同)
  • 这是有效的,它比@DanneManne答案恕我直言更简单.很好!:) (3认同)
  • 我至少通过accepts_nested_attributes发现了这个方法的问题.如果没有其他属性被更改,则嵌套保存不会触发before_validation.请参阅下面的答案以获得解决方案 (2认同)

Pau*_*eon 12

这是Benoit的答案,但包含在一个模块中,并覆盖了嵌套属性模型的边缘情况,其中destroy tickbox是模型上唯一改变的东西.

它将适用于模型上的所有附件.

# 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
Run Code Online (Sandbox Code Playgroud)

  • 上面的示例应该在您的问题或模型文件夹中.在你想要的模型中,只需在任何`has_attached_file`语句下面添加"include DeletableAttachment"行 (2认同)
  • 在rails3中,您还需要attr_accessible:"delete _#{name}" (2认同)

小智 5

记得将它添加到您的Page模型中:

attr_accessible :image_delete
Run Code Online (Sandbox Code Playgroud)