Subir múltiples archivos con JQuery, Rails y almacenarlos en la Base de Datos
Carlos Mathiasen publicó esto el 03/08/10 en Noticias, Ruby. 2 comentariosHay veces que el usuario necesita subir archivos, pero de una manera “masiva”, no guardando de a uno. Un claro ejemplo de esto es GoogleDocs,
que te deja subir varios documentos a la vez, antes de empezar a verlos.
Utilizando un plugin de jquery, en rails esto se hace de una manera muy transparente.
El plugin en cuestión se llama MultiFileUpload, en su página encontraremos una buena documentación de como usarlo correctamente
Lo que nos interesa es como implementarlo en rails y que todos estos archivos que seleccionamos se almacenen en nuestra base de datos.
Para comenzar tenemos que incluir las librerias del plugin en el aplication.html.erb
<% javascript_include_tag :default, 'multiple-file-upload/jquery.MultiFile.js', 'multiple-file-upload/jquery.MetaData.js' %>
En nuestra vista creamos el formulario, para subir los archivos
<% form_for(:archivo_digital, :html => {:multipart => true },:url => create_archivo_digital_path) do |f| %> <ul id="form"> <%= file_field_tag :files, :class => 'multi file', :name => 'pdf_files[]'%> <li> <%= f.submit 'Subir' %> <%= f.submit 'Cancelar' %></li> </ul> <% end %>
Expliquemos un poco el código:
En necesario establecer :multipart => true, para que el formulario admita la carga de archivos.
file_field_tag nos crea el tag para poder abrir el cuadro de diálogo de carga de archivos de un navegador:
:class => ‘multi file’, esta clase es la que utiliza MultiFileUpload para hacer la magia de subir varios archivos
:name => ‘pdf_files[]‘ esto es muy necesario, porque el plugin crea un arreglo con todos los archivos, pero para que ruby sepa
que nos referimos a un arreglo tenemos que poner [].
Por último tenemos dos botones, el de Subir, que va a subir todos los archivos de una sola vez y el de Cancelar, que hará lo propio.
En nuestro controller vamos a tener
#Renderiza el formulario para subir los archivos def new @archivo_digital = ArchivoDigital.new respond_to do |format| format.html end end def create respond_to do |format| if params[:commit] == "Subir" unless params[:pdf_files].blank? params[:pdf_files].each do |archivo| params[:archivo_digital][:nombre_archivo] = archivo params[:archivo_digital][:archivo] = archivo.read @archivo_digital = ArchivoDigital.new(params[:archivo_digital]) if @archivo_digital.save flash[:notice] = 'Archivo agregado' end end format.html{redirect_to archivos_digitales_path} else flash[:error] = 'Debe seleccionar al menos un archivo' end else format.html{redirect_to archivos_digitales_path} end end end
Expliquemos un poco el código:
Sobre el primer método no hay mucho que decir, solo nos renderiza el formulario que creamos en el paso anterior
El método create es el que hace todo, para empezar tenemos una condición donde pregunta si params[:commit] == “Subir”
esto es para que diferencie entre el botón subir y el cancelar. Cuando presionamos un botón, rails inmediatamente manda un parámetro, llamado
commit con el nombre del botón. Con está condición lo que hacemos es darle tareas diferentes a cada botón.
Si no se cumple la condición, es porque se presionó el botón “Cancelar” y nos redirigirá al listado de archivos.
En caso de que la condición se cumpla, tenemos otro condicional: unless params[:pdf_files].blank?, esto es para saber si se seleccionó algun archivo_digital
y caso contrario muestra un flash[:error]. Si se cumple la condición, recorremos el arreglo y vamos guardando en nuestra base de datos el nombre del
archivo y el archivo en sí.
Bueno, esto es una manera sencilla de subir archivos de forma “masiva” con Jquery y Rails, cualquier cosa no duden en preguntar
2 comentarios
Trackbacks and Pingbacks
-
[...] This post was mentioned on Twitter by IPCorp Blog, Carlos Mathiasen. Carlos Mathiasen said: Subir múltiples archivos con JQuery, Rails y almacenarlos en la Base de Datos http://bit.ly/bSL2v0 [...]
hola , queria felicitarte por tu pagina , es excelente.
Te mando un abrazo
Publicado el 3 Agosto 2010 a las 20:23. Permalink.