arrow_back Volver
Inicio keyboard_arrow_right Artículos keyboard_arrow_right Artículo

Subir archivos a la nube con Ruby on Rails

Uriel Hernández

CTO de Código Facilito

av_timer 2 Min. de lectura

remove_red_eye 11599 visitas

calendar_today 17 Octubre 2014

Cuando manejamos o transferimos gigas o teras de archivos, resulta más barato y conveniente hacerlo utilizando servicios cloud como http://http//aws.amazon.com/es/s3/ o https://cloud.google.com/storage/ cuyos costos de transferencia y almacenamiento son mucho menores a almacenarlos en tu propio servidor, además de que dichos servicios replican los archivos en diferentes servidores a modo que servirlos al cliente es más rápido, además de que guardan un respaldo de ellos.
No voy a adentrarme mucho en el cálculo de costos de dichos servicios, porque no es un cálculo sencillo, en cambio voy a explicarles como integrar su aplicación en Ruby on Rails con servicios cloud:
Para probar ambos servicios, vas a necesitar una tarjeta de crédito, porque será ahí donde van a cobrarte lo que almacenes o transfieras, si sólo harás unas cuantas pruebas, no alcanzarás ni a los centavos de costo. Para Google Cloud, vas a necesitar una cuenta aquí: https://cloud.google.com/storage/docs/signup?csw=1 .

El código

Vamos a subir los archivos utilizando un par de Gemas, por un lado vamos a subir los archivos usando PaperClip: https://github.com/thoughtbot/paperclip y por otro lado subiremos al servicio cloud los mismos archivos utilizando Fog: http://fog.io/
Para comenzar agregamos a nuestro Gemfile lo siguiente:
gem "fog"
gem "paperclip", "~> 4.2"
Y ejecutamos el bundle en la terminal (o el CMD) para instalar las gemas nuevas:
bundle install
Generamos un modelo para guardar en una tabla referencias a los archivos que vamos a guardar:
rails g model Attachment
Ese modelo requiere tener ciertos campos para trabajar con PaperClip, los agregamos con una migración:
rails g migration add_column_archivo_to_attachments
La migración generada tiene que quedar así:
  def self.up
    change_table :attachments do |t|
      t.attachment :archivo
    end
  end
  def self.down
    remove_attachment :attachments, :archivo
  end
Ejecutamos las migraciones desde la terminal:
rake db:migrate
Y bueno, la base de datos ya está lista, ahora sólo necesitamos configurar la funcionalidad, una parte considerablemente fácil con PaperClip y Fog.
Al modelo Attachment vamos a agregar lo siguiente:
do_not_validate_attachment_file_type :archivo #No es seguro
has_attached_file :archivo 
La parte que dice "no es seguro" necesita modificarse por alguna de las validaciones de archivos de PaperClip, en este caso no vamos a validar qué tipo de archivo esperamos que suba el usuario, así que agregamos el método mencionado. has_attached_file es un método también de PaperClip que agrega la funcionalidad a nuestro modelo para procesar y guardar archivos. Ahora configuremos la parte Cloud, ¿qué tan difícil es? Muy sencillo, configuremos el modelo Attachment para que quede de la siguiente manera:
has_attached_file :archivo, 
    :storage => :fog,
    :fog_credentials => {provider: 'Google', 
    google_storage_access_key_id: 'XXX', 
    google_storage_secret_access_key: 'XXX'},
    :fog_directory => "Nombre de tu bucket"
Este es un ejemplo para Google Cloud Storage, para que funcione tendrás que reemplazar las XXX por tus propias credenciales, mismas que tienes que adquirir aquí: https://code.google.com/apis/console en la sección de Google Cloud Storage / Interoperable Access. Además deberás crear un bucket aquí: https://console.developers.google.com, los buckets son como nombres de carpetas, sólo que son globales a través de todo el almacenamiento de Google, tendrás que elegir un nombre único.
Si deseas, en cambio, utilizar Amazon S3, puedes encontrar las modificaciones a la configuración aquí: http://fog.io/storage/
Para finalizar necesitas agregar un formulario para subir archivos que al menos contenga un campo tipo archivo con name attachment[archivo], como el siguiente:
<%= form_for(attachment) do |f| %>
  
  <div class="form-group">
    <%= f.file_field :archivo %>
  </div>
  <div class="actions">
    <%= f.submit "Subir archivo", class: "btn be-green white" %>
  </div>
<% end %>
Y claro, no olvidemos el controlador:
class AttachmentsController < ApplicationController
def create
@attachment = Attachment.new(attachment_params)
if attachment.save
redirect_to @attachment, alert: "Se guardo tu archivo"
else
redirect_to @attachment, notice: "No pudimos agregar tu archivo"
end
end
private
def attachment_params
     params.require(:attachment).permit(:archivo)
   end
end
Y listo. Recuerda que si quieres aprender Rails a fondo, puedes hacerlo a través del curso de Backend Avanzado, al que puedes accesar aquí: http://beta.codigofacilito.com/premium/backend en donde aprenderás a conectar Facebook y Twitter con tu aplicación, a crear tiendas en línea con PayPal, crear relaciones avanzadas en la base de datos, testing, AJAX y mucho más.