Deleting a Paperclip Attachment in Activeadmin
Asked Answered
S

5

7

I'm using paperclip to add image attachments to several models and Activeadmin to provide a simple admin interface.

I have this code in my activeadmin model file which allows for image uploads:

form :html => { :enctype => "multipart/form-data"} do |f|
f.inputs "Details" do
  f.input :name
  f.input :subdomain
end
f.inputs "General Customisation" do
  f.input :standalone_background,  :hint => (("current image:<br/>").html_safe + f.template.image_tag(f.object.standalone_background.url(:thumb))).html_safe, :as => :file
end
end

which works fine. All of the images I'm attaching like this are optional and so I'd like to give the user the option to remove a previously added image but can't work out how to do this in Activeadmin. All of the example I've seen are for situations where the attachments are managed through a separate has_many association rather than being part of the main model.

Does anyone know of a way to do this?

Sin answered 11/2, 2012 at 15:34 Comment(0)
C
2

In your active admin view

form :html => { :enctype => "multipart/form-data"} do |f|
f.inputs "Details" do
  f.input :name
  f.input :subdomain
end
f.inputs "General Customisation" do
  f.input :standalone_background,  :hint => (("current image:<br/>").html_safe +   f.template.image_tag(f.object.standalone_background.url(:thumb))).html_safe, :as => :file
  f.input :remove_standalone_background, as: :boolean, required: false, label: "remove standalone background"
 end
end

In your model

You could define a status flag like bellow

attr_writer :remove_standalone_background

def remove_standalone_background
  @remove_standalone_background || false
end

OR (depreciated in rails 3.2)

attr_accessor_with_default : standalone_background,false

before_save :before_save_callback

And

def before_save_callback
  if self.remove_standalone_background
    self.remove_standalone_background=nil
  end
end
Colchicum answered 3/4, 2013 at 10:45 Comment(1)
You forgot to actually delete the attachment with standalone_background.clearKamalakamaria
D
1

You could implement this by creating a custom method. This can be done

member_action :custom_action, :method => :get do
//code
end

Also you should add a custom column with a link such as

index do
  column "Custom" do |item|
    link_to "Custom action", "/admin/items/custom_action"
  end
end
Duplessismornay answered 14/3, 2012 at 14:51 Comment(0)
C
1

Another option is to have a status flag for the attachment or image. Before saving the edited object, you unlink the image.

Candlestand answered 18/6, 2012 at 6:31 Comment(0)
S
1

Thank you for your help guys. This is the final working code...

admin/product.rb

f.input :image, required: false, hint: (("Current image:<br/>").html_safe + f.template.image_tag(f.object.image.url(:thumb))).html_safe
f.input :remove_image, as: :boolean, required: false, label: "Remove Image"

models/product.rb

attr_writer :remove_image

def remove_image
  @remove_image || false
end

before_validation { self.image.clear if self.remove_image == '1' }
Surely answered 11/4, 2014 at 18:57 Comment(0)
H
0

Although accepts_nested_attributes_for(:foo, allow_destroy: true) only works with ActiveRecord associations like belongs_to we can borrow from its design to have paperclip attachment deletion work in a similar way.

(To understand how nested attributes work in Rails see http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html).

Add a <attachment_name>_attributes= writer method like below to your model that already uses has_attached_file:

has_attached_file :standalone_background

def standalone_background_attributes=(attributes)
  # Marks the attachment for destruction on next save,
  # if the attributes hash contains a _destroy flag
  # and a new file was not uploaded at the same time:
  if has_destroy_flag?(attributes) && !standalone_background.dirty?
    standalone_background.clear
  end
end

The <attachment_name>_attributes= method calls Paperclip::Attachment#clear to mark the attachment for destruction when the model is next saved.

Next open the existing app/admin/your_model_here.rb file (use the correct file path for your app) and setup strong parameters to permit the _destroy flag nested attribute on <attachment_name>_attributes:

ActiveAdmin.register YourModelHere do

  permit_params :name, :subdomain,
    :standalone_background,
    standalone_background_attributes: [:_destroy]

In the same file, add a nested _destroy checkbox to the ActiveAdmin form block. This checkbox must be nested within <attachment_name>_attributes using semantic_fields_for (or one of the other nested attributes methods provided by formtastic).

form :html => { :enctype => "multipart/form-data"} do |f|
  f.inputs "Details" do
    ...
  end
  f.inputs "General Customisation" do
    ...
    if f.object.standalone_background.present?
      f.semantic_fields_for :standalone_background_attributes do |fields|
        fields.input :_destroy, as: :boolean, label: 'Delete?'
      end
    end
  end
end

Your form should now show a delete checkbox when there is an attachment present. Checking this checkbox and submitting a valid form ought to delete the attachment.

Source: https://github.com/activeadmin/activeadmin/wiki/Deleting-Paperclip-Attachments-with-ActiveAdmin

Hep answered 4/4, 2017 at 5:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.