rails active ruby-on-rails stream paperclip

ruby-on-rails - active - rails gem upload file



escribir secuencia en clip (5)

Quiero almacenar el archivo adjunto recibido con el uso de clip. Del correo electrónico obtengo part.body y no tengo idea de cómo ponerlo en el modelo de clip de papel. Por ahora, creo el archivo temporal y escribo port.body en él, almaceno este archivo en paperclip y elimino el archivo. Así es como lo hago con el archivo temporal:

l_file = File.open(l_path, "w+b", 0644) l_file.write(part.body) oAsset = Asset.new( :email_id => email.id, :asset => l_file, :header => h, :original_file_name => o, :hash => h) oAsset.save l_file.close File.delete(l_path)

: asset es mi campo ''has_attached_file''. ¿Hay alguna manera de omitir la creación de archivos y hacer algo como: asset => part.body en Asset.new?


Así es como lo haría, suponiendo que uses la gema del correo para leer el correo electrónico. necesitarás todo el correo electrónico ''parte'', no solo part.body

file = StringIO.new(part.body) #mimic a real upload file file.class.class_eval { attr_accessor :original_filename, :content_type } #add attr''s that paperclip needs file.original_filename = part.filename #assign filename in way that paperclip likes file.content_type = part.mime_type # you could set this manually aswell if needed e.g ''application/pdf''

ahora solo use el objeto de archivo para guardar en la asociación Paperclip.

a = Asset.new a.asset = file a.save!

Espero que esto ayude.


Desde ruby ​​1.9, puedes usar StringIO y define_singleton_method:

def attachment_from_string(string, original_filename, content_type) StringIO.new(string).tap do |file| file.define_singleton_method(:original_filename) { original_filename } file.define_singleton_method(:content_type) { content_type } end end


La respuesta de Barlow es buena, pero efectivamente está aplicando parches a la clase StringIO. En mi caso, estaba trabajando con Mechanize :: Download # body_io y no quería contaminar la clase, lo que ocasionó que aparecieran errores inesperados en la aplicación. Así que defino los métodos en la metaclass de instancias así:

original_filename = "whatever.pdf" # Set local variables for the closure below content_type = "application/pdf" file = StringIO.new(part.body) metaclass = class << file; self; end metaclass.class_eval do define_method(:original_filename) { original_filename } define_method(:content_type) { content_type } end


Me gusta mucho la respuesta de gtd, pero puede ser más simple.

file = StringIO.new(part.body) class << file define_method(:original_filename) { "whatever.pdf" } define_method(:content_type) { "application/pdf" } end

Realmente no hay necesidad de extraer la "metaclase" en una variable local, solo agregue alguna clase al objeto.


Utilicé una técnica similar para desplegar imágenes en clips

esto debería funcionar, pero no se ha probado:

io = part.body def io.original_filename; part.original_file_name || ''unknown-file-name''; end asset = Asset.new(:email=>email) asset.asset = io

Cuando asignamos el IO directamente a la instancia de paperclip, necesita tener un .original_file_name, así que eso es lo que estamos haciendo en la segunda línea.