2011-02-06 20 views
19

Tengo dificultades para descubrir cómo evitar que Paperclip elimine la versión anterior de un archivo adjunto (imagen).Evitar que Paperclip elimine/sobrescriba archivos adjuntos en la actualización

Tengo un modelo, Sitio, que tiene un archivo adjunto, logotipo. Me gustaría mantener los logos antiguos, ya que estaré al tanto de los cambios en el modelo y me gustaría ver el historial de los logotipos.

Estoy siguiendo los cambios en otro modelo, que tiene una referencia a las rutas de archivos. Mi problema es que al actualizar un sitio con un nuevo logotipo, Paperclip primero vaciará el logotipo viejo.

Me sorprende que no haya una opción que pueda cambiar para evitar que Paperclip limpie el antiguo archivo adjunto antes de crear el nuevo.

¿Alguna idea?

Respuesta

32

Hay una nueva opción que dice clip para preservar archivos adjuntos viejos:

https://github.com/thoughtbot/paperclip/commit/65e8d4f6de50732d8e1b https://github.com/thoughtbot/paperclip/issues/60

fácil de usar:

has_attached_file => :attachment, 
        :styles => { :thumb => 100x100! }, 
        :preserve_files => true 

No está documentado con todo y tomó algo de investigación para encontrar lo que quería compartir aquí.

+0

Gracias. +1 desde aquí, a pesar de que no resolvió mi problema en ese momento. – simonwh

+5

A día de hoy, 'preserve_files' parece obsoleto, para la última API de clip: http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods:has_attached_file Ver' keep_old_files': conservar los archivos adjuntos existentes (original + tamaño cambiado) para que se elimine automáticamente cuando se borre o actualice un archivo adjunto. El valor predeterminado es falso. –

+1

@AdrienSchuler Leo esos dos como separados. 'preserve_files' mantendrá los archivos incluso si se elimina el registro principal, mientras que' keep_old_files' no da esta seguridad. –

1

Debido a que los archivos adjuntos se definen a nivel de clase, Paperclip interpola los símbolos en las cadenas utilizando su propia biblioteca de interpolación. Puede crear sus propias interpolaciones usando esta biblioteca.

Agregaría un campo al modelo llamado attachment_version o algo similar, y luego incrementaré este número de versión cada vez que se cambie el archivo. A continuación, cree una interpolación por él en un fichero de inicialización:

Paperclip.interpolates :version do |attachment, style| 
    attachment.instance.attachment_version 
end 

Ahora puede utilizar :version en sus cadenas:

class Model < ActiveRecord::Base 
    has_attached_file :something, :path => " :rails_root/public/somethings/etc/:version.:extension" 
end 

Ver the wiki documentation para más información.

[Actualización]

Después de algo de investigación en torno a (véanse los comentarios a esta respuesta), he llegado a la conclusión de que Paperclip se todavía eliminar el antiguo apego debido al código que se llama en Paperclip::Atachment#attach . Probablemente, la mejor forma de solucionar esto es crear un nuevo motor de almacenamiento basado en Paperclip::Storage::Filesystem y sobrescribir #flush_deletes. Tenga en cuenta que no hay forma de que en ese método se indique si un archivo se está poniendo en cola para su eliminación debido a que el modelo pertenece a su eliminación o si se está cargando un nuevo archivo en su lugar.

+0

Se me ocurre que Paperclip aún puede borrar el archivo antiguo, justo por defecto, aunque los nombres no coinciden ... –

+1

Este parece ser el caso. 'Paperclip :: Attachment # assign' llama a' # clear', que llama a 'queue_existing_for_delete', que a su vez hace exactamente lo que parece. Usted * podría * crear un nuevo motor de almacenamiento basado en https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/storage/filesystem.rb y modificar '# flush_deletes' según sea necesario. –

+0

Gracias BinaryMuse, que parece ser la mejor manera de hacerlo en este momento. Debería crear una respuesta ;-) – simonwh

0

lib/paperclip_monkey_patch.RB:

module Paperclip 
    class Attachment 
    def clear 
    # nop 
    #raise "hell" 
    # op 
    instance_write(:file_name, nil) 
    instance_write(:content_type, nil) 
    instance_write(:file_size, nil) 
    instance_write(:updated_at, nil) 
    end 
end 
end 

A continuación, agregue esta línea en la parte superior de cualquier archivo que elimina los archivos adjuntos:

require 'paperclip_monkey_patch'

Gracias a Ruby Forum

Cuestiones relacionadas