Ruby-on-rails Rails Paperclip 如何删除附件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4435826/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:53:06  来源:igfitidea点击:

Rails Paperclip how to delete attachment?

ruby-on-railsrubypaperclip

提问by jyoseph

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

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

I've only found one example of this hereand could not get that to work, it just wouldn't delete and there was nothing in the logs to say why. I wanted to do something like this on the form:

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

<%- unless @page.new_record? || [email protected]? -%>
    <%= f.check_box :image_delete, :label => 'Delete Image' %>
<%- end -%>

(page is the name of the model, image is the attribute name which holds the attachment)

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

But how do I detect that checkbox and more importantly, how do I delete the image? I appreciate any help!

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

回答by DanneManne

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:

首先,当您在 form_for(看起来像您)中创建一个 check_box 时,默认情况下,表单应将 :image_delete 发送为“1”(如果选中)和“0”(如果未选中)。方法声明如下所示:

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:

为了完成您通过复选框删除图像的方式,可以在您的 Page 模型中添加如下内容:

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.

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

回答by Benoit B.

has_attached_file :asset

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.

无需销毁资产,Paperclip 会做到。

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

在形式form.check_box(:delete_asset)就足够了。

回答by Paul Odeon

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.

这是 Benoit 的答案,但包含在一个模块中,并涵盖了嵌套属性模型的边缘情况,其中销毁复选框是模型上唯一更改的内容。

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

回答by Glenn McW

remember to add this to your Page model too:

请记住也将其添加到您的页面模型中:

attr_accessible :image_delete

回答by JBlake

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_filedefinitions.

Paul 解决方案的修改版本,以支持 Rails 5 自定义属性。我只是希望有一种方法可以在has_attached_file定义之前将模块包含在文件的顶部。

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

回答by stwienert

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

能够以更少的代码实现这一点,只需delete_attachment在模型端实现 a 即可。:

class MyModel < ApplicationRecord
  has_attached_file :image

  def image_delete=(other)
    self.image = nil if other == "1" or other == true
  end
end