Manejo de imágenes con ActiveStorage
Cuando se trata de trabajar con imágenes puede ser un poco complicado, empezando por trabajar con el servicio de almacenamiento de tu gusto. Pero para eso existe ActiveStorage que facilita mucho el trabajo de imágenes. Y para esto estaremos trabajando con la versión de Rails 5.2
¿Qué es ActiveStorage?
ActiveStorage es una herramienta que facilita la subida de archivos a almacenamientos en la nube como AWS, Google Cloud Storage o Microsoft Azure Storage y adjunta esos archivos convirtiéndolos en Active Record objects. Viene con un servicio local basado en disco para desarrollo y pruebas, y admite la duplicación de archivos a otros servicios para copias de seguridad y migraciones.
Con ActiveStorage, una aplicación puede transformar las cargas de imágenes, generar representaciones de imágenes de cargas sin imágenes como archivos PDF y videos, y extraer metadatos de archivos arbitrarios.
Configuración
Para todo esto ActiveStorage utiliza dos tablas en la base de datos llamadas active_storage_blobs
y active_storage_attachments
.
Después de crear una nueva aplicación, hay que ejecutar el siguiente comando:
rails active_storage:install
Y completando con el siguiente comando para poder generar las tablas a través de una migración.
rails db:migrate
Declaramos el servicio de almacenamiento que utilizaremos en config/storage.yml, la siguiente configuración dependerá del servicio que utilicemos:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
cloudinary:
service: Cloudinary
cloud_name: ""
api_key: ""
api_secret: ""
Después de esto hay que indicar que servicio se utilizará mediante la configuración Rails.application.config.active_storage.service
en la siguiente ruta config/environments/development.rb
config.active_storage.service = :cloudinary
Adjuntar archivos a registros
Supongamos que tienes un modelo User y desea que cada usuario tenga su propio avatar, para ello se declara lo siguiente:
Class User < ApplicationRecord
has_one_attached :avatar
La propiedad has_one_attached
configura una asignación uno a uno entre registros y archivos, es decir que cada registro contiene un archivo adjunto; y se acompaña de la etiqueta :avatar
para hacer referencia a ella en el siguiente formulario:
<%= form_for(attachment) do |f| %>
<div>
<%= f.file_field :avatar %>
</div>
<div>
<%= f.submit "Cambiar avatar" %>
</div>
<% end %>
Y se pasa a través de los strongs params en el controlador de la siguiente forma:
class UserController < ApplicationController
user.avatar.attach(user_params[:avatar])
def user_params
params.require(:user).permit(:name, :avatar)
end
end
Comprobar si un usuario tiene un avatar.
user.avatar.attached?
Y para poder visualizar la imagen, se hace de la siguiente manera:
<div class="avatar">
<%= image_tag(url_for(user.avatar)) %>
</div>
De igual manera si requieres utilizar más de una imágen para un modelo se haría lo siguiente:
class User < ApplicationRecord
has_many_attached :images
end
class UserController < ApplicationController
user.images.attach(user_params[:images])
def user_params
params.require(:user).permit(:name, images: [])
end
end