2010-11-03 28 views
13

Tengo un archivo de rake, que lee contenido a través de HTTP y quiero usar Paperclip para almacenar el contenido cargado en Amazon S3. Funciona bien cuando proporciono un archivo local, pero me gustaría establecer el contenido como una cadena y establecer el tipo de contenido manualmente.Cómo usar Paperclip sin un archivo, solo con una cadena?

Lo siguiente no funciona. no se emite ningún error, la entrada de base de datos se actualiza, pero ningún archivo se crea en S3:

p.attachment = "Test" 
p.attachment_file_name = "test.txt" 
p.attachment_content_type = "text/plain" 
p.attachment_file_size = "Test".size 
p.attachment_updated_at = Time.now 
p.save 

supongo que podría escribir un archivo temporal con el contenido de mi, pero eso sería una solución bastante ineficiente.

Respuesta

2

No, debe crear un archivo con su cadena.

Basta con mirar el código fuente Paperclip: https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/attachment.rb#L77 y https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/iostream.rb#L5

cuando se asigna algo con my_model.attachment =, Paperclip quiere un objeto de archivo.

+0

Eso es lamentable. ¿Crees que debería usar algo más que Paperclip entonces? Me gustaría mantener la posibilidad de cambiar de S3 a un sistema de archivos fácilmente, pero no tengo cargas de archivos de usuario, por lo que Paperclip podría ser la opción incorrecta. – Jan

+1

has mirado en carrierwave: https://github.com/jnicklas/carrierwave que parece una gran alternativa ... –

8

Es un poco tarde, pero lo logró mediante la creación de un archivo temporal utilizando rubí 1.9.2 carriles de 3.1

file = Tempfile.new(["file_name", '.txt']) 
file.write("my test string".force_encoding('utf-8')) 
p.attachment = file 
+0

brilliant .. No sé por qué funciona, pero funciona. –

+0

Esto realmente creará un archivo ... https://ruby-doc.org/stdlib-1.9.3/libdoc/tempfile/rdoc/Tempfile.html – olivervbk

40

Para evitar ensuciar el sistema de archivos con archivos temporales, puede utilizar StringIO como en:

p.attachment = StringIO.new(your_string) 
+1

Una pequeña solución. Una vez que hagas esto, establece el nombre del archivo adjunto con 'p.attachment_file_name = 'test.txt'' y ya estás listo. –

0

similares a Aarons pero con el método del bloque adecuado según lo sugerido por Ruby:

... uno siempre debe llamar desvincular o cerrar en un bloque de seguridad.

file = Tempfile.new('test.txt') 

begin 
    file.write("Test") 

    p.attachment = file 
    p.save    

    # Whatever else you might need to do with the TempFile. 

ensure 
    file.close 
    file.unlink # Deletes the temp file. 
end 
3

Por tanto clip y carierwave que terminan creando una clase como esta. Tiene ambos métodos necesarios para simular una carga de archivos que les gusta ver.

class FakeFileIO < StringIO 
    attr_reader :original_filename 
    attr_reader :path 

    def initialize(filename, content) 
    super(content) 
    @original_filename = File.basename(filename) 
    @path = File.path(filename) 
    end 
end 

funciona como un sueño

Cuestiones relacionadas