Dette er den siste artikkelen i serien "Opplasting med skinner". I de siste par månedene har vi allerede diskutert Shrine, Dragonfly og Carrierwave gems. Dagens gjest er Paperclip by Thoughtbot, et selskap som forvalter edelstener som FactoryGirl og Bourbon.
Paperclip er trolig den mest populære vedleggsløsningen for Rails (over 13 millioner nedlastinger), og med god grunn: den har mange funksjoner, et stort fellesskap og grundig dokumentasjon. Så forhåpentligvis er du ivrig etter å lære mer om denne perlen!
I denne artikkelen lærer du hvordan du:
Kildekoden for denne artikkelen er tilgjengelig på GitHub.
Før vi dykker inn i koden, la oss først diskutere noen advarsler som du trenger å vite om for å kunne jobbe med Paperclip:
fil
kommandoen bør være tilgjengelig fra kommandolinjen. For Windows er den tilgjengelig via Development Kit, så følg disse instruksjonene hvis du ikke har DevKit installert ennå.Når du er klar, fortsett og opprett et nytt Rails-program (jeg skal bruke Rails 5.0.2) uten standard testing suite:
Skinner nye UploadingWithPaperclip -T
Drop i Paperclip-perlen:
perle "paperclip", "~> 5.1"
Installer den:
bunt installasjon
Anta at vi lager en bokhylleapplikasjon som presenterer en liste over bøker. Hver bok vil ha en tittel, en beskrivelse, en forfatters navn og et deksjonsbilde. For å starte, generer og bruk følgende migrering:
skinner g modell Boktittel: strengbeskrivelse: tekstbilde: vedleggsforfatter: strengskinner db: migrere
Legg merke til feste
type som presenteres for oss av Paperclip. Under hetten skal det skape fire felt for oss:
image_file_name
IMAGE_FILE_SIZE
image_content_type
image_updated_at
I motsetning til Shrine og Carrierwave gems, har Paperclip ikke en egen fil med konfigurasjoner. Alle innstillinger er definert inne i selve modellen ved hjelp av has_attached_file
metode, så legg den til nå:
has_attached_file: bilde
Før vi fortsetter til hoveddelen, la oss også opprette en kontroller sammen med noen visninger og ruter.
Vår kontroller vil være veldig grunnleggende:
klasse 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
Her er en index vis og delvis:
Bokhylle
<%= link_to 'Add book', new_book_path %>
Nå ruter:
Rails.application.routes.draw gjør ressurser: bøker rot til: 'bøker # indeks' slutt
Hyggelig! La oss nå gå videre til hoveddelen og kode på ny handling og et skjema.
Alt i alt er det enkelt å laste opp med Paperclip. Du trenger bare å tillate den tilsvarende attributtet (i vårt tilfelle er det bilde
attributt, og vi har allerede tillatt det) og presentere et filfelt i skjemaet ditt. La oss gjøre det nå:
Legg til bok
<%= 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 %>
Med dette oppsettet kan du allerede begynne å utføre opplastinger, men det er også en god idé å introdusere noen valideringer også.
Valideringer i Paperclip kan skrives med gamle hjelpere som validates_attachment_presence
og validates_attachment_content_type
eller ved å ansette validates_attachment
metode for å definere flere regler samtidig. La oss holde fast ved det sistnevnte alternativet:
validates_attachment: image, content_type: content_type: /\Aimage\/.*\z/, størrelse: mindre_: 1.megabyte
Koden er veldig enkel, som du kan se. Vi krever at filen skal være et bilde mindre enn 1 megabyte i størrelse. Merk at hvis valideringen mislykkes, vil ingen etterbehandling bli utført. Paperclip har allerede noen feilmeldinger angitt for det engelske språket, men hvis du vil støtte andre språk, inkluderer du paperclip-i18n-perlen i din Gemfile.
En annen viktig ting å nevne er at Paperclip krever at du validerer innholdstype eller filnavn for alle vedlegg, ellers vil det oppstå en feil. Hvis du er 100% sikker på at du ikke trenger slike valideringer (som er et sjeldent tilfelle), bruk do_not_validate_attachment_file_type
å eksplisitt si hvilke felt som ikke bør kontrolleres.
Vi har lagt til valideringer, la oss også vise feilmeldinger i vårt skjema:
<% if object.errors.any? %>Noen feil ble funnet:
<%= render 'shared/errors', object: book %>
Ok, så nå skal de opplastede bildene vises på en eller annen måte. Dette gjøres ved å bruke IMAGE_TAG
hjelper og a url
metode. Lage en vise fram utsikt:
<%= @book.title %> av <%= @book.author %>
<%= image_tag(@book.image.url) if @book.image.exists? %><%= @book.description %>
Vi viser bare et bilde hvis det virkelig finnes på stasjonen. Videre, hvis du bruker skylagring, vil Paperclip utføre en nettverksforespørsel og sjekke filens eksistens. Selvfølgelig kan denne operasjonen ta litt tid, så du kan bruke nåværende?
eller fil?
metoder istedenfor: de vil bare sørge for at image_file_name
feltet er fylt med noe innhold.
Som standard lagres alle vedlegg inne i offentlig / system mappe, så du vil sannsynligvis utelukke den fra versjonskontrollsystemet:
offentlig / system
Å vise en full URI til filen kan imidlertid ikke alltid være en god ide, og du må kanskje forvirre det på en eller annen måte. Den enkleste måten å aktivere obfuscation er ved å gi to parametere til has_attached_file metode
:
url: "/system/:hash.:extension", hash_secret: "longSecretString"
De riktige verdiene blir interpolert inn i url
automatisk. hash_secret
er et obligatorisk felt, og den enkleste måten å generere den på er å bruke:
skinner hemmelig
I mange tilfeller er det foretrukket å vise et miniatyrbilde med en forhåndsdefinert bredde og høyde for å lagre båndbredde. Paperclip løser dette ved å bruke stiler: hver stil har et navn og et sett med regler, som dimensjoner, format, kvalitet osv.
Anta at vi vil ha det opprinnelige bildet og dets miniatyrbilde skal konverteres til JPEG-format. Miniatyrbildet skal beskjæres til 300x300px:
has_attached_file: bilde, stiler: thumb: ["300x300 #",: jpeg], original: [: jpeg]
#
er en geometrisk innstilling som betyr: "Beskjære om nødvendig samtidig som du opprettholder aspektforhold."
Vi kan også tilby flere konverteringsalternativer for hver stil. For eksempel, la oss gi 70% kvalitet for tommelen mens du fjerner alle metadata og 90% kvalitet for det opprinnelige bildet for å gjøre det litt mindre:
has_attached_file: bilde, stiler: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70-strip", original: "-kvalitet 90"
Hyggelig! Vis miniatyrbildet og gi lenken til det opprinnelige bildet:
<%= link_to(image_tag(@book.image.url(:thumb)), @book.image.url, target: '_blank') if @book.image.exists? %>
Merk at i motsetning til Carrierwave, for eksempel, kan Paperclip ikke tillate deg å skrive @ book.image.thumb.url
.
Hvis du av en eller annen grunn ønsker å oppdatere opplastede bilder manuelt, kan du bruke følgende kommandoer til å oppdatere bare miniatyrer, legge til manglende stiler eller oppdatere alle bilder:
rake paperclip: refresh: thumbnails CLASS = Book
rake paperclip: refresh: missing_styles CLASS = Book
rake paperclip: refresh CLASS = Book
Som alle lignende løsninger, kan du med Paperclip laste opp filer til skyen. Ut av esken har den støtte til S3 og Fog-adaptere, men det finnes også tredjeparts edelstener for Azure og Dropbox. I denne delen vil jeg vise deg hvordan du integrerer Paperclip med Amazon S3. Først, slipp i aws-sdk-perlen:
perle 'aws-sdk'
Installer den:
bunt installasjon
Deretter gir du et nytt sett med alternativer til has_attached_file
metode:
has_attached_file: bilde, stiler: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70-strip", original: "-kvalitet 90", lagring :: s3, s3_credentials: access_key_id: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], bøtte: ENV ["S3_BUCKET"], s3_region: ENV ["S3_REGION"]
Her stikker jeg til dotenv-skinnene perlen for å sette miljøvariabler. Du kan gi alle verdier direkte inn i modellen, men ikke gjøre den offentlig tilgjengelig.
Det som er interessant er det s3_credentials
aksepterer også en bane til en YAML-fil som inneholder nøklene og et bøttenavn. Videre kan du angi forskjellige verdier for forskjellige miljøer som dette:
utvikling: access_key_id: key1 secret_access_key: secret1 produksjon: access_key_id: key2 secret_access_key: secret2
Det er det! Alle filene du laster opp, ligger nå i din S3-bøtte.
Anta at du ikke vil at de opplastede filene dine skal være tilgjengelige for alle. Som standard er alle opplastinger i skyen merket som offentlige, noe som betyr at alle kan åpne filen via direkte koblingen. Hvis du ønsker å presentere noen autorisasjonslogikk og sjekke hvem som kan se filen, må du sette inn s3_permissions
alternativ til :privat
som dette:
has_attached_file: bilde, stiler: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70-strip", original: "-kvalitet 90", lagring :: s3, s3_credentials: access_key_id: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], bøtte: ENV ["S3_BUCKET"], s3_region: ENV ["S3_REGION"], s3_permissions:
Nå, men ingen, unntatt for deg, vil kunne se filene. Derfor la oss lage en ny nedlasting
handling for BooksController
:
def nedlasting redirect_to @ book.image.expiring_url slutten
Denne handlingen vil ganske enkelt omdirigere brukere til bildet via en utgående link. Ved hjelp av denne tilnærmingen kan du nå introdusere en autorisasjonslogikk ved hjelp av perler som CanCanCan eller Pundit.
Ikke glem å sette medlemsruten:
ressurser: bøker gjør medlemmet få "nedlasting" slutten
Hjelperen skal brukes slik:
link_to ('View image', download_book_path (@book), mål: '_blank')
Vi har kommet til slutten av denne artikkelen! I dag har vi sett Paperclip, en vedleggsløsningsløsning for Rails, i handling og diskutert hovedkonseptene. Det er mye mer til denne perlen, så vær sikker på å se dokumentasjonen.
Jeg anbefaler også å besøke Paperclips wiki-side, da den presenterer en liste over "hvordan å" opplæringsprogrammer og en rekke lenker til tredjepartsmykker som støtter Azure og Cloudinary, og lar deg enkelt redusere opplastede filer.
Takk for at du bodde hos meg og ser deg snart!