Uno de los grandes beneficios de trabajar con una plataforma de desarrollo como es Ruby on Rails es que nos permite ahorrarnos lÃneas de código que en otras plataformas o frameworks nos llevarÃa tiempo y esfuerzo hacer que funcionara correctamente.
La importancia de la velocidad en el desarrollo de nuestras aplicaciones es cada vez más importante y Rails nos ofrece un desarrollo con menos esfuerzo y mucho mayor rapidez.
A continuación mostraré de qué forma se puede subir un video con formato FLV al servidor.
El primer paso, asumiendo que ya se encuentra instalado Rails en nuestro sistema, será crear un nuevo proyecto, para ello bastará con utilizar el comando rails seguido del nombre que queremos darle a nuestro proyecto.
Lo cual nos creará un nuevo directorio subirVideo en nuestro directorio actual, por lo que es importante estar en el directorio donde queremos crear nuestro proyecto.
Dentro de nuestro proyecto crearemos nuestro controlador videos que será el encargado de gestionar la subida del vÃdeo,para tal propósito se utiliza el comando generate que se encuentra dentro del directorio script de nuestro proyecto, la forma para crear el controlador es:
script/generate controller videos
Al ejecutar este comando se creará una serie de archivos y directorios:
exists app/controllers/
exists app/helpers/
create app/views/videos
exists test/functional/
exists test/unit/helpers/
create app/controllers/videos_controller.rb
create test/functional/videos_controller_test.rb
create app/helpers/videos_helper.rb
create test/unit/helpers/videos_helper_test.rb
A partir de este momento podemos empezar a desarrollar nuestra aplicación, abrimos el archivo videos_controller.rb y crearemos una nueva acción llamada index la cual será la endargada de mostrar el formulario que permitirá al usuario escoger el archivo que quiere subir. Nuestro archivo queda de la siguiente manera:
class VideosController < ApplicationController
def index
end
end
Lo siguiente que haremos será crear una vista en el directorio app/views/videos on el nombre index.html.erb para esa acción que creamos, en ésta se encontrará todo el código HTML que se mostrará en el navegador, lo que haremos será crear un archivo con el siguiente contenido:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Subir Video</title>
</head>
<body>
<div>
<% form_tag 'videos/upload', :id => 'subir', :multipart => true do %>
<h4>Escoja un video</h4>
<p>El video debe tener la extensión flv</p>
<%= file_field_tag "video" %><br />
<%= submit_tag "Subir video" %>
<% end %>
</div>
</body>
</html>
Que nos mostrará una pantalla como esta:

la lÃnea:
<% form_tag 'videos/upload', :id => 'subir', :multipart => true do %>
nos ayuda a crear un formulario, la función form_tag es de los llamados helpers que nos ayudan a reducir la cantidad de lineas de código haciendo que nuestras vistas sean prácticamente sólo HTML, ‘videos/upload’ es la dirección en donde se realizará la acción con los datos enviados por el formulario, :multipart => true indica que será un formulario que permitirá enviar archivos al servidor, :id => ’subir’ es el id que se le da al formulario cualquier otro atributo se podrÃa asignar usando la notación :atributo => ‘valor’
<%= file_field_tag "video" %> y <%= submit_tag "Subir video" %>
son al igual que form_tag helpers para definir inputs del tipo file y del tipo submit respectivamente, para file_field_tag, “video” es el name y el id que tendrá el campo y para submit_tag, “Subir video” será el valor que se mostrará en el botón.
Ya teniendo nuestra vista es necesario crear otra acción llamada upload que será donde se realicen las operaciones con el video una vez esté en el servidor.
def upload
if request.post?
#asigna la información del video en archivo
archivo = params[:video]
#nombre original del archivo
name =Â archivo.original_filename
#ruta donde se guardará el video
directory = "public/flv"
# crear la ruta del archivo
path = File.join(directory, name)
extensionArchivo = name.slice(name.rindex("."), name.length).downcase
#verifica que la extensión sea la correcta
if extensionArchivo == '.flv'
# crear el archivo
File.open(path, "wb") { |f| f.write(archivo.read) }
#guarda la información que se mostrará
@archivoGuardado = true
@nombreArchivo = name
else
#en caso de que no sea correcta la extensión muestra un mensaje de error
render :text => '<p>El archivo debe tener la extensión flv</p> de click <a href="../videos"> aquÃ</a> para volver a intentarlo'
end
end
end
Lo primero que hacemos es verificar que se haya enviado el formulario mediante post utilizando:
Sà el archivo se envio lo primero que hacemos es asignar el video que subimos a una variable en estea caso archivo params nos permite acceder a los datos enviados mediante POST y para acceder a cada campo enviado utilizamos params[:nombreDelCampo] en este caso params[:video], utilizaremos en nombre que tenÃa el archivo al ser subido por el usuario asà que almacenamos el nombre original en la variable name y en directory almacenamos la ruta donde se guardará el archivo en el servidor (”public/flv”), en path tendremos la ruta completa del archivo por ejemplo: public/flv/miVideo.flv, hasta ahora no hemos almacenado el archivo en el servidor, primero debemos saber si la extensión es la correcta para eso la obtenemos mediante:
extensionArchivo = name.slice(name.rindex("."), name.length).downcase
que lo que hace es extraer la cadena que se forma a partir del útimo punto a la derecha del nombre del archivo hasta el final del nombre del archivo y lo convierte en minúsculas, asà no importa que la extensión sea .flv o .FLV.
Si la extensión es la correcta entonces pasamos el archivo al directorio public/flv mediante:
File.open(path, "wb") { |f| f.write(archivo.read) }
que crea un archivo en la ruta path (incluyendo el nombre) a partir del contenido del archivo que subimos almacenado en archivo, wb nos indica que el archivo se abre para escritura en modo binario.
Después de crear el archivo guardamos los datos en variables que podremos utilizar en la vista upload, que es el nombre y una variable que nos indica si el archivo se guardó.
La vista que nos mostrará que el archivo se guardó correctamente como se mencionó antes tendrá el nombre upload y tendra el siguiente contenido:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Archivo procesado</title>
</head>
<body>
<% if @archivoGuardado %>
<p>El archivo <%= @nombreArchivo %> se subio correctamente</p>
<%end%>
</body>
</html>
Que comprueba que el archivo se haya guardado corectamente para mostrar un mensaje como este:
El archivo miVideo.flv se subio corectamente
En caso de que la extensión del archivo no fuera ni .flv ni .FLV entonces inmediatamente nos mostrará un mensaje de error como este:
Para hacer esto hacemos uso de render :text para mostrar el mensaje.
Hasta ahora la aplicación funciona correctamente pero serÃa mejor que la subida del archivo se realizara en segundo plano para que el usuario no crea que la página está congelada, para hacer esto haremos uso de Javascript y un iframe oculto.
Agregaremos un iframe a la vista index y un área para los posibles mensajes de error, entonces nuestra vista quedará de la siguiente forma:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<%= stylesheet_link_tag 'estilos' %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag "validar" %>
<title>Subir Video</title>
</head>
<body>
<div>
<% form_tag 'videos/upload', :id => 'subir', :multipart => true do %>
<h4>Escoja un video</h4>
<p>El video debe tener la extensión flv</p>
<%= file_field_tag "video" %><br />
<%= submit_tag "Subir video" %>
<% end %>
</div>
<div id="mensajes">
</div>
<div id="contenedorIframe">
<iframe name="Upload" id="Upload"></iframe>
</div>
</body>
</html>
Debemos ocultar el iframe a la vista del usuario para ello creamos una hoja de estilos en la carpeta public/stylesheets llamada estilos.css con el siguiente contenido:
Se pudo evitar esto haciendo:
<iframe name="Upload" id="Upload" style="display:none"></iframe>
pero es mejor separar el contenido de la presentación.
Para incluir la hoja de estilos usamos el helper stylesheet_link_tag con el nombre de nuestra hoja de estilos, la única condicion es que esté en el directorio stylesheets:
<%= stylesheet_link_tag 'estilos' %>
Cargamos las librerÃas de javascript necesarias para realizar las nuestras acciones, utilizamos e l helper javascript_include_tag con la misma condicion que las hojas de estilo, debe estar en el directorio javascripts, utilizo :defaults para que todas las librerias incluidas por defecto en Rails se carguen pero basta con ‘prototype’ ya que es la única que se utiliza, crearemos un archivo llamado validar.js en public/javascripts y lo incluimos:
<%= javascript_include_tag "validar" %>
en este archivo pondremos lo siguiente:
window.onload = function()
{
var formulario = $('subir');
formulario.target = "Upload";
 formulario.onsubmit = function(){
var listoEnvio = true;
var archivo = $('video').value;
var extension = (archivo.substring(archivo.lastIndexOf("."))).toLowerCase();
if(extension == '')
{
$('mensajes').update("Seleccione un archivo");
listoEnvio = false;
}
else
{
//Si existe archivo se comprueba que sea .flv
if(extension != '.flv')
{
//En caso de que no sea esa la extensión se muestra un mensaje y
// listoEnvio se vuelve false
$('mensajes').update("Seleccione un archivo del tipo correcto");
listoEnvio = false;
}
else
{
//En caso de que sea la extensión correcta se muestra un gif
//mientras se sube el archivo
$('mensajes').update('<img src="/images/cargando.gif" />');
}
}
//En caso de error no se envÃa el archivo al servidor
return listoEnvio;
}
}
Asignamos nuestro formulario subir a la variable formulario y cambiamos el target hacia el iframe que creamos antes
formulario.target = "Upload";
Lo cambiamos mediante javascript sobre todo por accesisbilidad, para que aquellos que tengan javascript desactivado puedan utilizar normalmente el formulario, ahora debemos hacer la validación de la extensión al momento de que se envie el formulario y al igual que hicimos con Rails comprobamos la extensión y mostramos los mensajes en el área que destinamos a los posibles mensajes que quisieramos mostrar

En caso de error asignamos false a listoEnvio para evitar que se envÃe el formulario, si todo marcha bien entonces se enviará al servidor y mostrará una imagen aanimada mientras se sube el archivo.

El siguiente paso es hacer que la vista upload responda a la página principal mediante javascript, debemos agregar algunas lineas de código para adaptarlo:
<% if @archivoGuardado %>
<noscript>
<p>El archivo <%= @nombreArchivo %> se subio correctamente</p>
</noscript>
<script type="text/javascript">
if(parent.document.getElementById("contenedorIframe"))
{
parent.$("subir").reset();
parent.$("mensajes").update("El archivo se subio correctamente")
}
</script>
<%end%>
Lo ahora lo que hace es que si Javascript no está activado mostrará el mensaje en pantalla pero si está activado y upload se está ejecutando en el iframe el formulario se reiniciará y se mostrará un mensaje indicando que el archivo se subio correctamente, se utiliza parent porque el iframe “Upload” es hijo de la ventana principal entonces si llegara a ejecutar esta accion por separado comprobarÃa que esista el elemento contenedorIframe para hace la acción si no no hará nada.

Y listo, tenemos un formulario que sube un video en formato FLV con Javascript no obstrusivo.