Pour joindre des fichiers à nos données nous avions l'habitude d'utiliser des gems comme Paperclip ou CarrierWave. Mais, depuis la version 5.2, Ruby On Rails embarque un module appelé Active Storage qui va permettre de gérer plus facilement les fichiers attachés à nos models.

Installation d'active_storage

Pour commencer à utiliser ActiveStorage il faut commencer par créer les migrations nécessaires.

rails active_storage:install 

Cette migration va générer deux tables dans la base de données

  • active_storage_blobs qui va faire référence aux différents fichiers envoyés
  • active_storage_attachments qui permettra de ratacher les blobs aux champs de nos différents models.

Il faudra ensuite migrer la base de données

rails db:migrate

Pour ensuite configurer l'upload de fichier il faudra modifier le fichier config/storage.yml afin de définir où placer les fichiers qui seront uploadés sur le serveur. Vous pouvez choisir un dossier local à votre machine ou utiliser des services tiers comme Amazon S3, Microsoft Azure...

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
    access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
    secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
    region: us-east-1
    bucket: your_own_bucket

Il faudra ensuite lancer la commande

rails credentials:edit

Pour ajouter les accès à Amazon S3 par exemple.

Attacher un ou plusieurs fichiers à un Modèle

Pour attacher un fichier à un modèle il suffit d'utiliser les méthodes has_one_attached ou has_many_attached

class User < ApplicationRecord
  has_one_attached :avatar
  has_many_attached :pictures
end

Le model pourra alors recevoir un ou plusieurs fichier lors de sa modification (pensez à autoriser les paramètres).

params.require(:user).permit(:email, :password_digest, :avatar, pictures: [])

Enfin vous pouvez modifier vos formulaire pour permettre à l'utilisateur d'uploader un ou plusieurs fichiers.

<%= form.file_field :avatar, :class => "form-control" %>
<%= form.file_field :pictures, :multiple => true, :class => "form-control" %>

Enfin pour afficher une image un simple appel à la méthode correspondant au nom du champs suffit.

<%= image_tag @user.avatar %>

Redimensionner et Transformer

Vous pouvez aussi demander une version spécifique de votre image qui sera généré sur demande :

<%= image_tag user.avatar.variant(resize_to_fit: [100, 100]) %>

Pour que cela fonctionne, rails va se reposer sur MiniMagick et il vous faudra installer la gem image_processing

gem 'image_processing', '~> 1.2'

Pour les utilisateurs de capistrano

Attention à bien placer vos images si vous utilisez capistrano (car souvent le dossier storage n'est pas partagé entre les releases). Pensez à placer les images dans un dossier partagé pour éviter tous problèmes avec l'utilisation d'ActiveStorage.

La documentation

Pour plus de détails sur l'utilisation d'ActiveStorage, n'hésitez pas à faire un tour sur la documentation.