2008-09-11 9 views
14

Pronto comenzaré un proyecto que requiere soporte para archivos binarios de gran tamaño. Me gustaría usar Ruby on Rails para la aplicación web, pero me preocupa el soporte BLOB. En mi experiencia con otros lenguajes, marcos y bases de datos, los BLOB a menudo se pasan por alto y, por lo tanto, tienen una funcionalidad deficiente, difícil y/o defectuosa.Rails Soporte de Binary Stream

¿RoR spport BLOBs adecuadamente? ¿Hay problemas que se arrastran una vez que ya estás comprometido con Rails?

BTW: Quiero utilizar PostgreSQL y/o MySQL como la base de datos back-end. Obviamente, el soporte de BLOB en la base de datos subyacente es importante. Por el momento, quiero evitar enfocarme en las capacidades BLOB de DB; Estoy más interesado en cómo Rails reacciona. Idealmente, Rails debería ocultarme los datos de la base de datos, así que debería poder cambiar de uno a otro. Si esto es no el caso (es decir, hay algún problema con el uso de Rails con un DB en particular), por favor hágalo.

ACTUALIZACIÓN: Además, no estoy hablando solo de ActiveRecord aquí. Tendré que manejar archivos binarios en el lado HTTP (carga de archivos de manera efectiva). Eso significa obtener acceso a los encabezados y flujos HTTP adecuados a través de Rails. He actualizado el título y la descripción de la pregunta para reflejar esto.

Respuesta

8

1 de attachment_fu

utilizo attachment_fu en una de mis aplicaciones y debe almacenar los archivos de la base de datos (por razones molestos que están fuera del alcance de esta convo).

La (una?) Cosa complicada con BLOB que he encontrado es que necesitas una ruta de código separada para enviar los datos al usuario; no puedes simplemente alinear una ruta en el sistema de archivos como lo harías si fuera un archivo simple de Jane.

p. Ej. Si usted está almacenando información avatar, no se puede simplemente hacer:

<%= image_tag @youruser.avatar.path %> 

usted tiene que escribir algo de lógica envoltorio y utilizar send_data, por ejemplo, (A continuación es sólo un ejemplo w/attachment_fu, en la práctica que había necesidad de secar Esta arriba)

send_data(@youruser.avatar.current_data, :type => @youruser.avatar.content_type, :filename => @youruser.avatar.filename, :disposition => 'inline') 

Por desgracia, por lo que yo sé attachment_fu (no tengo la última versión) no hace inteligente Envolver para ti, tienes que escribirlo tú mismo.

P.S. Ver la edición de su pregunta - Attachment_fu maneja todas las cosas molestas que menciona - acerca de la necesidad de conocer las rutas de archivos y toda esa porquería - EXCEPTO el pequeño problema cuando se almacena en la base de datos. Darle una oportunidad; es el estándar para aplicaciones de rieles. ¡Si insiste en reinventar la rueda, el código fuente de attachment_fu debería documentar la mayoría de los errores también!

5

Usted puede utilizar el tipo :binary en su migración ActiveRecord y también limitar el tamaño máximo :

class BlobTest < ActiveRecord::Migration 
    def self.up 
    create_table :files do |t| 
     t.column :file_data, :binary, :limit => 1.megabyte 
    end 
    end 
end 

ActiveRecord expone el BLOB (o CLOB) contenido como un rubí de cadena.

0

Busque en el plugin, x_send_file también.

"El complemento XSendFile proporciona una interfaz sencilla para enviar archivos a través del encabezado X-Sendfile HTTP. Esto permite que su servidor web sirva el archivo directamente desde el disco, en lugar de transmitirlo a través de su proceso Rails. mucha memoria si está utilizando Mongrel. No todos los servidores web admiten este encabezado. YMMV ".

No estoy seguro si se puede usar con Blobs, puede ser solo para archivos en el sistema de archivos. Pero probablemente necesite algo que no ate el servidor web que transmite grandes cantidades de datos.

13

En cuanto a la transmisión, puede hacerlo todo de una manera (al menos con la memoria) eficiente. En el lado de la carga, los parámetros del archivo en formularios se abstraen como objetos IO de los que se puede leer; en el lado de descarga, busque en la forma de render :text => que toma un argumento Proc:

render :content_type => 'application/octet-stream', :text => Proc.new { 
    |response, output| 
    # do something that reads data and writes it to output 
} 

Si el material se encuentra en archivos en el disco, sin embargo, las soluciones antes mencionadas sin duda funcionan mejor.

+0

Rails ahora tiene [send_data] (http://apidock.com/rails/ActionController/DataStreaming/send_data). – m33lky