Acesta este ultimul articol din seria "Încărcarea cu șine". În ultimele două luni am discutat deja pietrele Altarului, Dragonfly și Carrierwave. Vizitatorul de astăzi este Paperclip de Thoughtbot, o companie care administrează pietre precum FactoryGirl și Bourbon.
Paperclip este probabil cea mai populară soluție de administrare a atașamentelor pentru Rails (mai mult de 13 milioane de descărcări) și pentru un motiv bun: are o mulțime de caracteristici, o comunitate excelentă și o documentație amănunțită. Deci, sperăm că sunteți dornici să aflați mai multe despre această bijuterie!
În acest articol veți învăța cum să:
Codul sursă pentru acest articol este disponibil pe GitHub.
Înainte de a ne arunca cu capul în cod, să discutăm în primul rând despre unele avertismente pe care trebuie să le cunoașteți pentru a lucra cu Paperclip:
fişier
comanda ar trebui să fie disponibilă din linia de comandă. Pentru Windows este disponibil prin Development Kit, deci urmați aceste instrucțiuni dacă nu aveți încă instalat DevKit.Când sunteți gata, continuați și creați o nouă aplicație Rails (voi folosi Rails 5.0.2) fără suita de testare implicită:
șine noi UploadingWithPaperclip -T
Puneți în bijuterie din cartelă:
gem "agrafă", "~> 5,1"
Instalați-l:
instalare pachet
Să presupunem că creăm o aplicație pentru rafturi care prezintă o listă de cărți. Fiecare carte va avea un titlu, o descriere, un nume de autor și o imagine de copertă. Pentru a începe, generați și aplicați următoarea migrare:
rails g model Titlu carte: descriere șir: text imagine: atașament autor: string șir db: migrate
Rețineți atașament
tip care este prezentat pentru noi de Paperclip. Sub capota, se vor crea patru câmpuri pentru noi:
image_file_name
IMAGE_FILE_SIZE
image_content_type
image_updated_at
Spre deosebire de pietrele Shrine și Carrierwave, Paperclip nu are un fișier separat cu configurații. Toate setările sunt definite în interiorul modelului însuși folosind has_attached_file
metoda, adăugați-o acum:
has_attached_file: imagine
Înainte de a trece la partea principală, să creați un controler împreună cu unele vederi și rute.
Controlorul nostru va fi foarte simplu:
clasa 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
Aici este un index vizualizare și parțial:
Raft de cărți
<%= link_to 'Add book', new_book_path %>
Acum rutele:
Rails.application.routes.draw face resurse: cărți rădăcină la: "cărți # index" sfârșitul
Frumos! Acum, să mergem la secțiunea principală și să codificăm nou acțiune și o formă.
În general, încărcarea cu Paperclip este ușoară. Trebuie doar să permiteți atributul corespunzător (în cazul nostru este vorba de imagine
atribut și l-am permis deja) și să prezinte un câmp de fișier în formularul dvs. S-o facem acum:
Adăugați o carte
<%= 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 %>
Cu această configurație, puteți începe deja să efectuați încărcări, dar este bine să introduceți și unele validări.
Validările din Paperclip pot fi scrise cu ajutorul unor agenți vechi cum ar fi validates_attachment_presence
și validates_attachment_content_type
sau prin angajarea validates_attachment
metoda de definire a mai multor reguli simultan. Să rămânem cu cea de-a doua opțiune:
validates_attachment: image, content_type: content_type: /\Aimage\/.*\z/, dimensiune: less_than: 1.megabyte
Codul este foarte simplu, după cum puteți vedea. Solicităm ca fișierul să fie o imagine mai mică de 1 megabyte. Rețineți că în cazul în care validarea nu reușește, nu se va efectua nicio postprocesare. Paperclip are deja unele mesaje de eroare setate pentru limba engleză, dar dacă doriți să acceptați alte limbi, includeți bijuteria paperclip-i18n în Gemfile.
Un alt lucru important este de menționat că Paperclip vă cere să validați tipul de conținut sau numele fișierului pentru toate atașamentele, altfel va crește o eroare. Dacă sunteți 100% sigur că nu aveți nevoie de astfel de validări (care este un caz rar), utilizați do_not_validate_attachment_file_type
pentru a spune în mod explicit câmpurile care nu trebuie verificate.
După adăugarea validărilor, să afișăm, de asemenea, mesaje de eroare în formularul nostru:
<% if object.errors.any? %>Au fost găsite unele erori:
<%= render 'shared/errors', object: book %>
Bine, deci imaginile încărcate ar trebui afișate cumva. Acest lucru se face folosind IMAGE_TAG
helper și a URL-ul
metodă. Creeaza o spectacol vedere:
<%= @book.title %> de <%= @book.author %>
<%= image_tag(@book.image.url) if @book.image.exists? %><%= @book.description %>
Afișăm o imagine numai dacă există cu adevărat pe unitate. În plus, dacă utilizați spațiu de stocare în cloud, Paperclip va efectua o solicitare de rețea și va verifica existența fișierului. Desigur, această operațiune poate dura ceva timp, deci puteți utiliza prezent?
sau fişier?
metode în schimb: ei vor pur și simplu să se asigure că image_file_name
câmpul este populat cu un anumit conținut.
Implicit, toate atașările sunt stocate în interiorul / Sistemul public , astfel încât probabil veți dori să o excludeți din sistemul de control al versiunilor:
/ Sistemul public
Cu toate acestea, este posibil ca afișarea unui fișier URI complet în fișier să nu fie întotdeauna o idee bună și este posibil să trebuiască să o înșelați cumva. Cea mai ușoară modalitate de a permite obfuscarea este prin furnizarea a doi parametri către metoda has_attached_file
:
url: "/system/:hash.:extension", hash_secret: "longSecretString"
Valorile corespunzătoare vor fi interpolate în URL-ul
automat. hash_secret
este un câmp obligatoriu și cel mai simplu mod de generare a acestuia este utilizarea:
șinele secrete
În multe cazuri, este preferabil să afișați o miniatură a imaginii cu o lățime și înălțime predefinită pentru a salva lățimea de bandă. Paperclip rezolvă această problemă prin utilizarea stilurilor: fiecare stil are un nume și un set de reguli, cum ar fi dimensiunile, formatul, calitatea etc..
Să presupunem că vrem ca imaginea originală și miniatură să fie convertite în format JPEG. Miniatură ar trebui tăiată la 300x300px:
has_attached_file: imagine, stiluri: thumb: ["300x300 #",: jpeg], original: [: jpeg]
#
este o setare de geometrie care înseamnă: "Decupați dacă este necesar păstrând în același timp raportul de aspect".
De asemenea, putem oferi opțiuni suplimentare de conversie pentru fiecare stil. De exemplu, să oferim 70% calitate pentru degetele mari, în timp ce eliminăm toate metadatele și 90% calitate pentru imaginea originală pentru ao face puțin mai mică:
has_attached_file: imagine, stiluri: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip", original: "-quality 90"
Frumos! Afișați miniaturile și furnizați link-ul către imaginea originală:
<%= link_to(image_tag(@book.image.url(:thumb)), @book.image.url, target: '_blank') if @book.image.exists? %>
Rețineți că, spre deosebire de Carrierwave, de exemplu, Paperclip nu vă permite să scrieți @ book.image.thumb.url
.
Dacă, din anumite motive, doriți să actualizați manual imaginile încărcate, puteți utiliza următoarele comenzi pentru a reîmprospăta numai miniaturile, a adăuga stiluri lipsă sau pentru a reîmprospăta toate imaginile:
rake paperclip: reîmprospătare: miniaturi CLASS = Rezervați
rake paperclip: refresh: missing_styles CLASS = Rezervați
rake colier: reîmprospătează CLASS = Rezervați
Ca toate soluțiile similare, Paperclip vă permite să încărcați fișiere în cloud. Din cutie, are suport pentru adaptoarele S3 și Fog, dar există și pietre pentru terțe părți pentru Azure și Dropbox. În această secțiune, vă voi arăta cum să integrați Paperclip cu Amazon S3. Mai întâi, aruncați bijuteria aws-sdk:
gem 'aws-sdk'
Instalați-l:
instalare pachet
Apoi, furnizați un nou set de opțiuni la has_attached_file
metodă:
has_attached_file: imagine, stiluri: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip" :: s3, s3_credentials: acces_key_id: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], cupă: ENV ["S3_BUCKET"], s3_region: ENV ["S3_REGION"]
Aici stau la gheața dotenv-șine pentru a stabili variabilele de mediu. Puteți furniza toate valorile direct în interiorul modelului, dar nu îl faceți public.
Ce e interesant este asta s3_credentials
acceptă, de asemenea, o cale către un fișier YAML care conține cheile și numele unei găleți. În plus, puteți seta diferite valori pentru medii diferite, cum ar fi:
dezvoltare: acces_key_id: key1 secret_access_key: secret1 producție: access_key_id: key2 secret_access_key: secret2
Asta e! Toate fișierele pe care le încărcați vor fi acum amplasate în galeria dvs. S3.
Să presupunem că nu doriți ca fișierele încărcate să fie disponibile pentru toată lumea. În mod prestabilit, toate încărcările în cloud sunt marcate ca fiind publice, ceea ce înseamnă că oricine poate deschide fișierul prin linkul direct. Dacă doriți să introduceți o logică de autorizare și să verificați cine poate vizualiza fișierul, setați-l s3_permissions
opțiunea pentru :privat
asa:
has_attached_file: imagine, stiluri: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip" :: s3, s3_credentials: acces_key_id: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], cupă: ENV ["S3_BUCKET"], s3_region: ENV [S3_REGION]
Acum, cu toate acestea, nimeni, cu excepția dvs., va putea să vadă fișierele. Prin urmare, să creăm un nou Descarca
acțiune pentru BooksController
:
def descărcați redirect_to @ book.image.expiring_url end
Această acțiune va redirecționa pur și simplu utilizatorii către imagine printr-un link care expiră. Folosind această abordare, puteți introduce acum orice logică de autorizare utilizând pietre precum CanCanCan sau Pundit.
Nu uitați să setați traseul membru:
resurse: cărțile fac membrii nu se termină "descărcare"
Ajutorul trebuie folosit în felul următor:
link_to ('Vizualizare imagine', download_book_path (@book), țintă: '_blank')
Am ajuns la sfârșitul acestui articol! Astăzi am văzut Paperclip, o soluție de gestionare a atașamentelor pentru Rails, în acțiune și am discutat despre principalele sale concepte. Există mult mai mult pentru această bijuterie, deci asigurați-vă că vedeți documentația sa.
De asemenea, vă recomand să vizitați pagina wiki Paperclip deoarece prezintă o listă de tutoriale "cum să" și o grămadă de link-uri către pietre de la terți care susțin Azure și Cloudinary și vă permit să micșorați cu ușurință fișierele încărcate.
Vă mulțumim că ați rămas cu mine și vă voi vedea în curând!