J'utilise Paperclip (avec Amazon s3) sur Rails 3. Je veux supprimer une pièce jointe existante sans la remplacer en utilisant une action de mise à jour.
Je n'ai trouvé qu'un exemple de cela ici et je n'ai pas pu faire fonctionner cela, il ne voulait tout simplement pas supprimer et il n'y avait rien dans les journaux pour dire pourquoi. Je voulais faire quelque chose comme ça sur le formulaire:
<%- unless @page.new_record? || [email protected]? -%>
<%= f.check_box :image_delete, :label => 'Delete Image' %>
<%- end -%>
(la page est le nom du modèle, l'image est le nom de l'attribut qui contient la pièce jointe)
Mais comment puis-je détecter cette case à cocher et, plus important encore, comment supprimer l'image? J'apprécie toute aide!
Tout d'abord, lorsque vous créez une case à cocher dans un form_for (qui vous ressemble), le formulaire doit par défaut envoyer: image_delete comme "1" si coché et "0" si non coché. La déclaration de méthode ressemble à ceci:
def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
Ce qui montre que vous pouvez attribuer d'autres valeurs si vous le souhaitez, mais cela est bien sûr facultatif.
Deuxièmement, l'appel pour supprimer manuellement une pièce jointe sans supprimer l'instance de modèle à laquelle elle est attachée est:
@page.image.destroy #Will remove the attachment and save the model
@page.image.clear #Will queue the attachment to be deleted
Et pour accomplir votre façon de supprimer les images via une case à cocher, ajoutez peut-être quelque chose comme ceci à votre modèle de 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
De cette façon, lorsque vous créez votre formulaire et ajoutez la case à cocher: image_delete, il chargera la valeur par défaut "0" à partir de l'instance de l'utilisateur. Et si ce champ est coché, le contrôleur mettra à jour l'image_delete à "1" et lorsque l'utilisateur sera enregistré, il vérifiera si l'image doit être supprimée.
has_attached_file :asset
=>
attr_accessor :delete_asset
before_validation { asset.clear if delete_asset == '1' }
Pas besoin de détruire les actifs, Paperclip le fera.
Sous la forme form.check_box(:delete_asset)
suffira.
C'est la réponse de Benoit, mais enveloppé dans un module, et couvrant le cas Edge des modèles d'attributs imbriqués où la case à cocher détruire est la seule chose qui a changé sur le modèle.
Il s'appliquera à toutes les pièces jointes du modèle.
# 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
n'oubliez pas d'ajouter cela à votre modèle de page également:
attr_accessible :image_delete
Version modifiée de la solution de Paul, pour prendre en charge Rails 5 attributs personnalisés. Je souhaite juste qu'il y ait un moyen d'inclure le module en haut du fichier, avant has_attached_file
définitions.
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