Det här är den sista artikeln i serien "Uploading with Rails". Under de senaste månaderna har vi redan diskuterat helgedomen, sländan och Carrierwave-pärlorna. Dagens gäst är Paperclip by Thoughtbot, ett företag som hanterar ädelstenar som FactoryGirl och Bourbon.
Paperclip är förmodligen den mest populära bilagan hanteringslösningen för Rails (mer än 13 miljoner hämtningar), och av god anledning: den har många funktioner, en stor gemenskap och grundlig dokumentation. Så förhoppningsvis är du ivrig att lära dig mer om denna pärla!
I den här artikeln lär du dig att:
Källkoden för den här artikeln finns på GitHub.
Innan vi dyker in i koden, låt oss först diskutera några försiktighetsåtgärder som du behöver veta om för att framgångsrikt kunna arbeta med Paperclip:
fil
Kommandot ska vara tillgängligt från kommandoraden. För Windows är det tillgängligt via Development Kit, följ så här instruktionerna om du inte har DevKit installerat än.När du är redo, fortsätt och skapa en ny Rails-applikation (jag ska använda Rails 5.0.2) utan standardtestprogrammet:
spårar nya UploadingWithPaperclip -T
Släpp i Paperclip-pärlan:
pärla "paperclip", "~> 5.1"
Installera det:
buntinstallation
Antag att vi skapar en bokhylla applikation som presenterar en lista med böcker. Varje bok har en titel, en beskrivning, en författares namn och en omslagsbild. För att börja skapa, skapa och tillämpa följande migrering:
skenor g modell Boktitel: strängbeskrivning: textbild: bifogad författare: strängskenor db: migrera
Notera bilaga
typ som presenteras för oss av Paperclip. Under huven kommer det att skapa fyra fält för oss:
image_file_name
IMAGE_FILE_SIZE
image_content_type
image_updated_at
I motsats till Shrine och Carrierwave-ädelstenar har Paperclip inte en separat fil med konfigurationer. Alla inställningar definieras inuti modellen själv med hjälp av has_attached_file
metod, så lägg till det nu:
has_attached_file: bild
Innan vi fortsätter till huvuddelen, låt oss också skapa en kontroller tillsammans med vissa vyer och rutter.
Vår controller kommer att vara väldigt grundläggande:
klass 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
Här är en index visa och delvis:
Bokhylla
<%= link_to 'Add book', new_book_path %>
Nu rutterna:
Rails.application.routes.draw gör resurser: böcker rot till: "böcker # index" slut
Trevlig! Nu går vi vidare till huvuddelen och kodar ny åtgärd och ett formulär.
Sammantaget är det enkelt att göra uppladdningar med Paperclip. Du behöver bara tillåta motsvarande attribut (i vårt fall är det bild
attribut, och vi har redan tillåtit det) och presentera ett filfält i din form. Låt oss göra det nu:
Lägg till 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 den här inställningen kan du redan börja ladda upp uppladdningar, men det är en bra idé att introducera några valideringar också.
Valideringar i Paperclip kan skrivas med gamla hjälpare som validates_attachment_presence
och validates_attachment_content_type
eller genom att anställa validates_attachment
metod för att definiera flera regler samtidigt. Låt oss hålla fast vid det senare alternativet:
validates_attachment: bild, content_type: content_type: /\Aimage\/.*\z/, storlek: less_than: 1.megabyte
Koden är väldigt enkel, som du kan se. Vi kräver att filen ska vara en bild mindre än 1 megabyte i storlek. Observera att om validering misslyckas kommer ingen efterbehandling att utföras. Paperclip har redan några felmeddelanden som är inställda för det engelska språket, men om du vill stödja andra språk, inkludera paperclip-i18n-pärlan i din Gemfile.
En annan viktig sak att nämna är att Paperclip kräver att du validerar innehållstyp eller filnamn för alla bilagor, annars kommer det att ge upphov till ett fel. Om du är 100% säker på att du inte behöver sådana valideringar (vilket är ett sällsynt fall), använd do_not_validate_attachment_file_type
för att uttryckligen säga vilka fält som inte ska kontrolleras.
Vi har lagt till valideringar, låt oss också visa felmeddelanden i vår form:
<% if object.errors.any? %>Några fel hittades:
<%= render 'shared/errors', object: book %>
Okej, så nu ska de uppladdade bilderna visas på något sätt. Detta görs genom att använda image_tag
hjälpen och a url
metod. Skapa en show se:
<%= @book.title %> av <%= @book.author %>
<%= image_tag(@book.image.url) if @book.image.exists? %><%= @book.description %>
Vi visar endast en bild om den verkligen finns på enheten. Dessutom, om du använder molnlagring, kommer Paperclip att utföra en nätverksförfrågan och kontrollera filens existens. Självklart kan denna operation ta lite tid, så du kan använda närvarande?
eller fil?
metoder istället: de kommer helt enkelt att se till att image_file_name
Fältet är fyllt med något innehåll.
Som standard lagras alla bilagor inuti offentliga / system mappen, så du kommer antagligen vilja utesluta den från versionskontrollsystemet:
offentliga / system
Att visa en fullständig URI till filen kanske inte alltid är en bra idé, och du kan behöva obfuscate det på något sätt. Det enklaste sättet att aktivera obfuscation är att ge två parametrar till has_attached_file metod
:
url: "/system/:hash.:extension", hash_secret: "longSecretString"
De korrekta värdena kommer att interpoleras i url
automatiskt. hash_secret
är ett obligatoriskt fält, och det enklaste sättet att generera det är att använda:
skenor hemlighet
I många fall föredras att visa en bilds miniatyrbild med viss fördefinierad bredd och höjd för att spara bandbredd. Paperclip löser detta genom att använda stilar: varje stil har ett namn och en uppsättning regler, som dimensioner, format, kvalitet etc..
Antag att vi vill att originalbilden och dess miniatyrbild ska konverteras till JPEG-format. Miniatyren ska beskäras till 300x300px:
has_attached_file: bild, stilar: thumb: ["300x300 #",: jpeg], original: [: jpeg]
#
är en geometrisk inställning som betyder: "Beskära om nödvändigt samtidigt som bildskärmsförhållandet bibehålls."
Vi kan också erbjuda ytterligare konverteringsalternativ för varje stil. Till exempel, låt oss ge 70% kvalitet för tummen medan du tar bort alla metadata och 90% kvalitet för originalbilden för att göra det lite mindre:
has_attached_file: bild, stilar: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: tumme: "-quality 70-strip", original: "-quality 90"
Trevlig! Visa miniatyren och ge länken till originalbilden:
<%= link_to(image_tag(@book.image.url(:thumb)), @book.image.url, target: '_blank') if @book.image.exists? %>
Observera att till skillnad från Carrierwave, till exempel, tillåter Paperclip inte dig att skriva @ book.image.thumb.url
.
Om du av någon anledning vill uppdatera uppladdade bilder manuellt, kan du använda följande kommandon för att bara uppdatera miniatyrbilder, lägga till saknade stilar eller uppdatera alla bilder:
rake paperclip: refresh: miniatyrer CLASS = Book
rake paperclip: refresh: missing_styles CLASS = Book
rake paperclip: refresh CLASS = Book
Liksom alla liknande lösningar kan du låta Paperclip ladda upp filer till molnet. Utanför lådan har den stöd för S3 och Fog-adaptrarna, men det finns också tredje parts pärlor för Azure och Dropbox. I det här avsnittet ska jag visa dig hur du integrerar Paperclip med Amazon S3. Först, släpp in aws-sdk-pärlan:
pärla "aws-sdk"
Installera det:
buntinstallation
Ange sedan en ny uppsättning alternativ till has_attached_file
metod:
has_attached_file: bild, stilar: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: tumme: "-quality 70-strip", original: "-kvalitet 90", lagring s3_credentials
Här håller jag fast vid dotenv-skenerns pärla för att ställa in miljövariabler. Du kan ge alla värden direkt inuti modellen, men gör det inte tillgängligt för allmänheten.
Vad är intressant är det s3_credentials
accepterar också en sökväg till en YAML-fil som innehåller dina nycklar och ett skopnamn. Dessutom kan du ställa in olika värden för olika miljöer som följande:
utveckling: access_key_id: key1 secret_access_key: secret1 produktion: access_key_id: key2 secret_access_key: secret2
Det är allt! Alla filer du laddar upp kommer nu att ligga i din S3-hink.
Antag att du inte vill att dina uppladdade filer ska vara tillgängliga för alla. Som standard är alla uppladdningar i molnet markerade som offentliga, vilket innebär att vem som helst kan öppna filen via direktlänken. Om du vill introducera viss behörighetslogik och kontrollera vem som kan visa filen, ställ in s3_permissions
alternativ till :privat
så här:
has_attached_file: bild, stilar: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: tumme: "-quality 70-strip", original: "-kvalitet 90", lagring :: s3, s3_credentials: access_key_id: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], hink: ENV ["S3_BUCKET"], s3_region: ENV ["S3_REGION"], s3_permissions:
Nu kommer dock ingen utom för dig att kunna se filerna. Låt oss därför skapa en ny ladda ner
åtgärd för BooksController
:
def nedladdning redirect_to @ book.image.expiring_url slutet
Denna åtgärd kommer helt enkelt att omdirigera användare till bilden via en utgående länk. Med hjälp av detta tillvägagångssätt kan du nu införa någon behörighetslogik med hjälp av pärlor som CanCanCan eller Pundit.
Glöm inte att ställa in medlemsleden:
resurser: böcker gör medlemmen få "nedladdning" slutet
Hjälpen ska användas så här:
link_to ('Visa bild', download_book_path (@book), target: '_blank')
Vi har kommit till slutet av denna artikel! Idag har vi sett Paperclip, en bilagslösningslösning för Rails, i aktion och diskuterat sina huvudkoncept. Det finns mycket mer till den här pärlan, så var säker på att se dokumentationen.
Jag rekommenderar också att du besöker Paperclips wikisida eftersom det presenterar en lista med "hur till" handledning och en massa länkar till tredjeparts ädelstenar som stöder Azure och Cloudinary och låter dig enkelt avgränsa uppladdade filer.
Tack för att du bodde hos mig och vi ses snart!