Ceci est le dernier article de la série "Uploading with Rails". Au cours des deux derniers mois, nous avons déjà discuté des joyaux des sanctuaires, des libellules et des Carrierwave. L’invité d’aujourd’hui est Paperclip de Thoughtbot, une entreprise qui gère des bijoux tels que FactoryGirl et Bourbon.
Paperclip est probablement la solution de gestion des pièces jointes la plus répandue pour Rails (plus de 13 millions de téléchargements), et ce pour une bonne raison: ses nombreuses fonctionnalités, son excellente communauté et sa documentation complète. J'espère que vous avez hâte d'en savoir plus sur ce joyau!
Dans cet article, vous apprendrez comment:
Le code source de cet article est disponible sur GitHub.
Avant de plonger dans le code, discutons d’abord certaines mises en garde que vous devez connaître pour pouvoir utiliser Paperclip:
fichier
La commande doit être disponible à partir de la ligne de commande. Pour Windows, il est disponible via le Kit de développement. Suivez donc ces instructions si DevKit n’est pas encore installé..Lorsque vous êtes prêt, créez une nouvelle application Rails (j'utiliserai Rails 5.0.2) sans la suite de tests par défaut:
rails nouveau UploadingWithPaperclip -T
Déposer dans le joyau du trombone:
bijou "trombone", "~> 5.1"
Installez-le:
installation groupée
Supposons que nous créons une application de bibliothèque qui présente une liste de livres. Chaque livre aura un titre, une description, le nom d'un auteur et une image de couverture. Pour commencer, générez et appliquez la migration suivante:
rails g model Titre de l'ouvrage: string description: image de texte: pièce jointe auteur: string rails db: migrate
Noter la attachement
type qui nous est présenté par Paperclip. Sous le capot, il va nous créer quatre champs:
nom_fichier_image
image_fichier_size
image_content_type
image_updated_at
Contrairement aux gemmes Shrine et Carrierwave, Paperclip n’a pas de fichier séparé avec des configurations. Tous les paramètres sont définis dans le modèle lui-même à l'aide du has_attached_file
méthode, ajoutez-le maintenant:
has_attached_file: image
Avant de passer à la partie principale, créons également un contrôleur avec quelques vues et itinéraires..
Notre contrôleur sera très basique:
classe BooksController < ApplicationController before_action :set_book, only: [:show, :download] def index @books = Book.order('created_at DESC') end def new @book = Book.new end def show end def create @book = Book.new(book_params) if @book.save redirect_to books_path else render :new end end private def book_params params.require(:book).permit(:title, :description, :image, :author) end def set_book @book = Book.find(params[:id]) end end
Voici un indice vue et une partielle:
Étagère à livres
<%= link_to 'Add book', new_book_path %>
Maintenant les itinéraires:
Rails.application.routes.draw do resources: books racine à: 'books # index' end
Agréable! Passons maintenant à la section principale et codons le Nouveau action et une forme.
Dans l’ensemble, il est facile de télécharger des images avec Paperclip. Vous devez uniquement autoriser l'attribut correspondant (dans notre cas, c'est le image
attribut, et nous l’avons déjà autorisé) et présente un champ de fichier dans votre formulaire. Faisons-le maintenant:
Ajouter un livre
<%= render 'form', book: @book %>
<%= form_for book do |f| %><%= f.label :title %> <%= f.text_field :title %><%= f.label :author %> <%= f.text_field :author %><%= f.label :description %> <%= f.text_area :description %><%= f.label :image %> <%= f.file_field :image %><%= f.submit %> <% end %>
Avec cette configuration, vous pouvez déjà commencer à effectuer des téléchargements, mais il est également bon de présenter quelques validations..
Les validations dans Paperclip peuvent être écrites en utilisant d'anciens helpers comme validates_attachment_presence
et validates_attachment_content_type
ou en employant le validates_attachment
méthode pour définir plusieurs règles à la fois. Restons avec cette dernière option:
validates_attachment: image, type_contenu: type_contenu: /\Aimage\/.***/, taille: moins_than: 1.mégaoctet
Le code est très simple, comme vous pouvez le voir. Nous exigeons que le fichier soit une image de moins de 1 Mo de taille. Notez que si la validation échoue, aucun post-traitement ne sera effectué. Paperclip contient déjà des messages d'erreur définis pour la langue anglaise, mais si vous souhaitez prendre en charge d'autres langues, incluez la gem paperclip-i18n dans votre Gemfile.
Une autre chose importante à noter est que Paperclip vous demande de valider le type de contenu ou le nom de fichier de toutes les pièces jointes, sinon une erreur se produira. Si vous êtes sûr à 100% de ne pas avoir besoin de telles validations (ce qui est un cas rare), utilisez do_not_validate_attachment_file_type
de dire explicitement quels champs ne doivent pas être vérifiés.
Après avoir ajouté les validations, affichons également les messages d'erreur dans notre formulaire:
<% if object.errors.any? %>Quelques erreurs ont été trouvées:
<%= render 'shared/errors', object: book %>
D'accord, les images téléchargées doivent maintenant être affichées. Ceci est fait en utilisant le image_tag
assistant et un url
méthode. Créer un spectacle vue:
<%= @book.title %> par <%= @book.author %>
<%= image_tag(@book.image.url) if @book.image.exists? %><%= @book.description %>
Nous affichons une image uniquement si elle existe vraiment sur le lecteur. De plus, si vous utilisez le stockage en nuage, Paperclip effectuera une requête réseau et vérifiera l’existence du fichier. Bien sûr, cette opération peut prendre un certain temps, vous pouvez donc utiliser le présent?
ou fichier?
méthodes à la place: ils veilleront simplement à ce que le nom_fichier_image
le champ est rempli avec du contenu.
Par défaut, toutes les pièces jointes sont stockées dans la public / système dossier, vous voudrez probablement l'exclure du système de contrôle de version:
public / système
Cependant, afficher un URI complet dans le fichier n'est peut-être pas toujours une bonne idée et vous devrez peut-être le masquer d'une manière ou d'une autre. Le moyen le plus simple d’activer l’obscurcissement consiste à fournir deux paramètres à la Méthode has_attached_file
:
url: "/system/:hash.:extension", hash_secret: "longSecretString"
Les valeurs appropriées seront interpolées dans le url
automatiquement. hash_secret
est un champ obligatoire, et le moyen le plus simple de le générer consiste à utiliser:
rails secret
Dans de nombreux cas, il est préférable d’afficher la vignette d’une image avec une largeur et une hauteur prédéfinies pour économiser la bande passante. Paperclip résout ce problème en utilisant des styles: chaque style a un nom et un ensemble de règles, telles que les dimensions, le format, la qualité, etc..
Supposons que nous voulions que l'image originale et sa vignette soient converties au format JPEG. La vignette doit être recadrée à 300x300px:
has_attached_file: image, styles: thumb: ["300x300 #",: jpeg], original: [: jpeg]
#
est un paramètre de géométrie signifiant: "Rogner si nécessaire tout en conservant les proportions".
Nous pouvons également fournir des options de conversion supplémentaires pour chaque style. Par exemple, fournissons une qualité de 70% pour les pouces tout en supprimant toutes les métadonnées et une qualité de 90% pour l'image d'origine afin de la réduire un peu:
has_attached_file: image, styles: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip", original: "-quality 90"
Agréable! Affichez la vignette et fournissez le lien vers l'image d'origine:
<%= link_to(image_tag(@book.image.url(:thumb)), @book.image.url, target: '_blank') if @book.image.exists? %>
Notez que contrairement à Carrierwave, par exemple, Paperclip ne vous permet pas d’écrire @ book.image.thumb.url
.
Si, pour une raison quelconque, vous souhaitez mettre à jour manuellement les images téléchargées, vous pouvez utiliser les commandes suivantes pour actualiser uniquement les vignettes, ajouter des styles manquants ou actualiser toutes les images:
rake paperclip: refresh: vignettes CLASS = Livre
rake paperclip: refresh: missing_styles CLASS = Livre
rake paperclip: refresh CLASS = Livre
Comme toutes les solutions similaires, Paperclip vous permet de télécharger des fichiers sur le cloud. Par défaut, il prend en charge les adaptateurs S3 et Fog, mais il existe également des joyaux tiers pour Azure et Dropbox. Dans cette section, je vais vous montrer comment intégrer Paperclip à Amazon S3. Tout d’abord, déposez la pierre précieuse aws-sdk:
gem 'aws-sdk'
Installez-le:
installation groupée
Ensuite, fournissez un nouvel ensemble d’options au has_attached_file
méthode:
has_attached_file: image, styles: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip", original: "-quality 90", stockage :: s3, s3_credentials: clé_accès: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], compartiment: ENV ["S3_BUCKET"]], s3_region: ENV ["S3_REGION"]
Ici, je m'en tiens à la gem dotenv-rails pour définir les variables d'environnement. Vous pouvez fournir toutes les valeurs directement dans le modèle, mais ne le rendez pas public..
Ce qui est intéressant c'est que s3_credentials
accepte également un chemin d'accès à un fichier YAML contenant vos clés et un nom de compartiment. De plus, vous pouvez définir différentes valeurs pour différents environnements, comme ceci:
développement: access_key_id: key1 secret_access_key: secret1 production: access_key_id: key2 secret_access_key: secret2
C'est tout! Tous les fichiers que vous téléchargez seront maintenant situés dans votre compartiment S3.
Supposons que vous ne voulez pas que vos fichiers téléchargés soient disponibles pour tout le monde. Par défaut, tous les téléchargements dans le nuage sont marqués comme publics, ce qui signifie que tout le monde peut ouvrir le fichier via le lien direct. Si vous souhaitez introduire une logique d’autorisation et vérifier qui peut visualiser le fichier, définissez le paramètre s3_permissions
option de :privé
comme ça:
has_attached_file: image, styles: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip", original: "-quality 90", stockage :: s3, s3_credentials: clé_accès: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], compartiment: ENV ["S3_BUCKET"]], s3_region: ENV ["S3_REGION"], s3_permissions: privé
Maintenant, cependant, personne à part vous ne pourra voir les fichiers. Par conséquent, créons un nouveau Télécharger
action pour la LivresContrôleur
:
def télécharger redirect_to @ book.image.expiring_url end
Cette action redirigera simplement les utilisateurs vers l'image via un lien expirant. En utilisant cette approche, vous pouvez maintenant introduire toute logique d’autorisation en utilisant des gemmes comme CanCanCan ou Pundit..
N'oubliez pas de définir la route des membres:
ressources: les livres ne sont-ils pas téléchargés? end end
L'assistant devrait être utilisé comme ceci:
link_to ('Voir l'image', download_book_path (@book), cible: '_blank')
Nous sommes arrivés à la fin de cet article! Aujourd'hui, nous avons vu Paperclip, une solution de gestion des pièces jointes pour Rails, en action et discuté de ses principaux concepts. Il y a beaucoup plus à ce bijou, alors assurez-vous de voir sa documentation.
Je vous recommande également de consulter la page wiki de Paperclip, qui présente une liste de didacticiels "Comment faire", ainsi que de nombreux liens vers des gemmes tierces prenant en charge Azure et Cloudinary et permettant de réduire facilement les fichiers téléchargés.
Merci de rester avec moi et à bientôt!