Hochladen mit Schienen und Büroklammer

Dies ist der letzte Artikel der "Uploading with Rails" -Serie. In den letzten Monaten haben wir bereits über die Edelsteine ​​Schrein, Libelle und Carrierwave gesprochen. Der heutige Gast ist Paperclip von Thoughtbot, einem Unternehmen, das Juwelen wie FactoryGirl und Bourbon verwaltet.

Paperclip ist wahrscheinlich die beliebteste Lösung zur Verwaltung von Anhängen für Rails (mehr als 13 Millionen Downloads), und das aus gutem Grund: Sie bietet viele Funktionen, eine großartige Community und eine umfassende Dokumentation. Hoffentlich möchten Sie gerne mehr über dieses Juwel erfahren!

In diesem Artikel erfahren Sie, wie Sie:

  • Bereiten Sie die Installation von Paperclip vor
  • Integrieren Sie Paperclip in eine Rails-Anwendung
  • Fügen Sie Anlagenvalidierungen hinzu
  • Erstellen Sie Miniaturansichten und Prozessbilder
  • Verschleiern Sie URLs
  • Speichern Sie Anhänge in Amazon S3
  • Sichern Sie Dateien in der Cloud, indem Sie eine Berechtigungslogik einführen

Der Quellcode für diesen Artikel ist auf GitHub verfügbar.

Vorbereitungen

Bevor wir in den Code eintauchen, sollten wir zunächst einige Vorbehalte besprechen, die Sie kennen sollten, um erfolgreich mit Paperclip arbeiten zu können:

  • Die neueste Version von Paperclip unterstützt Rails 4.2+ und Ruby 2.1+. Dieser Edelstein kann auch ohne Schienen verwendet werden.
  • ImageMagick muss auf Ihrem PC installiert sein (es ist für alle gängigen Plattformen verfügbar) und Paperclip sollte darauf zugreifen können.
  • Das Datei Der Befehl sollte über die Befehlszeile verfügbar sein. Für Windows ist es über das Development Kit verfügbar. Wenn Sie DevKit noch nicht installiert haben, folgen Sie diesen Anweisungen.

Wenn Sie bereit sind, erstellen Sie eine neue Rails-Anwendung (ich verwende Rails 5.0.2) ohne die Standard-Testsuite:

Schienen neu UploadingWithPaperclip -T

Büroklammer integrieren

Füge den Paperclip-Edelstein ein:

Gemfile

Juwel "Büroklammer", "~> 5.1"

Es installieren:

Bundle installieren

Angenommen, wir erstellen eine Bücherregalanwendung, die eine Liste von Büchern enthält. Jedes Buch hat einen Titel, eine Beschreibung, den Namen des Autors und ein Titelbild. Um zu beginnen, generieren Sie die folgende Migration und wenden Sie sie an:

Schienen g Modell Buchtitel: Zeichenfolge Beschreibung: Textbild: Autor der Anlage: Zeichenfolge Schienen db: migrate

Beachten Sie das Befestigung Typ, der von Paperclip für uns präsentiert wird. Unter der Haube werden wir vier Felder für uns erstellen:

  • Bilddateiname
  • image_file_size
  • image_content_type
  • image_updated_at

Im Gegensatz zu den Schrein- und Carrierwave-Edelsteinen verfügt Paperclip nicht über eine separate Datei mit Konfigurationen. Alle Einstellungen werden innerhalb des Modells mit Hilfe von festgelegt has_attached_file Methode, so fügen Sie es jetzt hinzu:

models / book.rb

has_attached_file: image

Bevor Sie mit dem Hauptteil fortfahren, erstellen wir auch einen Controller mit einigen Ansichten und Routen.

Controller, Ansichten und Routen erstellen

Unser Controller wird sehr einfach sein:

books_controller.rb

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

Hier ist ein Index Ansicht und ein Teil:

views / books / index.html.erb

Bücherregal

<%= link_to 'Add book', new_book_path %>
    <%= render @books %>

Ansichten / Bücher / _book.html.erb

  • <%= link_to book.title, book_path(book) %> durch <%= book.author %>
  • Nun die Routen:

    config / routes.rb

    Rails.application.routes.draw do ressourcen: bucht root auf: 'books # index' end 

    Nett! Gehen wir nun zum Hauptteil und codieren Sie die Neu Aktion und ein Formular.

    Dateien hochladen

    Alles in allem ist das Hochladen mit Paperclip einfach. Sie müssen nur das entsprechende Attribut zulassen (in unserem Fall ist das das Bild Attribut, und wir haben es bereits erlaubt) und ein Dateifeld in Ihrem Formular präsentieren. Lass es uns jetzt machen:

    views / books / new.html.erb

    Buch hinzufügen

    <%= render 'form', book: @book %>

    Ansichten / Bücher / _form.html.erb

    <%= 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 %>

    Mit diesem Setup können Sie bereits mit dem Durchführen von Uploads beginnen, es ist jedoch eine gute Idee, einige Validierungen einzuführen.

    Validierungen hinzufügen

    Validierungen in Paperclip können mit Hilfe alter Helfer geschrieben werden validates_attachment_presence und validates_attachment_content_type oder durch die Verwendung der validates_attachment Methode, um mehrere Regeln gleichzeitig zu definieren. Bleiben wir bei der letzteren Option:

    models / book.rb

     validates_attachment: image, content_type: content_type: /\Aimage\/.*\z/, Größe: less_than: 1.megabyte

    Der Code ist wirklich einfach, wie Sie sehen können. Die Datei muss ein Bild mit einer Größe von weniger als 1 Megabyte sein. Wenn die Validierung fehlschlägt, wird keine Nachbearbeitung durchgeführt. Für die Büroklammer sind bereits einige Fehlermeldungen für die englische Sprache festgelegt. Wenn Sie jedoch andere Sprachen unterstützen möchten, fügen Sie die Büroklammer-i18n in Ihren Ordner ein Gemfile.

    Zu beachten ist auch, dass Paperclip die Überprüfung des Inhaltstyps oder Dateinamens aller Anhänge erfordert. Andernfalls wird ein Fehler ausgegeben. Wenn Sie zu 100% sicher sind, dass Sie solche Überprüfungen nicht benötigen (was in seltenen Fällen der Fall ist), verwenden Sie do_not_validate_attachment_file_type um explizit zu sagen, welche Felder nicht geprüft werden sollen.

    Nachdem Sie Validierungen hinzugefügt haben, zeigen wir auch Fehlermeldungen in unserem Formular an:

    views / shared / _errors.html.erb

    <% if object.errors.any? %> 

    Einige Fehler wurden gefunden:

      <% object.errors.full_messages.each do |message| %>
    • <%= message %>
    • <% end %>
    <% end %>

    Ansichten / Bücher / _form.html.erb

    <%= render 'shared/errors', object: book %>

    Bilder anzeigen

    Okay, jetzt sollten die hochgeladenen Bilder irgendwie angezeigt werden. Dies geschieht mit der image_tag Helfer und a url Methode. Ein ... kreieren Show Aussicht:

    Ansichten / Bücher / show.html.erb

    <%= @book.title %> durch <%= @book.author %>

    <%= image_tag(@book.image.url) if @book.image.exists? %>

    <%= @book.description %>

    Wir zeigen ein Bild nur dann an, wenn es wirklich auf dem Laufwerk vorhanden ist. Wenn Sie Cloud-Speicher verwenden, führt Paperclip außerdem eine Netzwerkanforderung aus und überprüft das Vorhandensein der Datei. Natürlich kann dieser Vorgang einige Zeit in Anspruch nehmen vorhanden? oder Datei? stattdessen Methoden: Sie stellen einfach sicher, dass die Bilddateiname Das Feld ist mit etwas Inhalt gefüllt.

    URI-Verschleierung

    Standardmäßig werden alle Anhänge in gespeichert öffentlich / system Ordner, so dass Sie es wahrscheinlich vom Versionskontrollsystem ausschließen möchten: 

    .Gitignore

    öffentlich / system

    Das Anzeigen eines vollständigen URIs für die Datei ist jedoch möglicherweise nicht immer eine gute Idee, und Sie müssen ihn möglicherweise irgendwie verschleiern. Die einfachste Möglichkeit, die Verschleierung zu aktivieren, besteht darin, dem Parameter zwei Parameter bereitzustellen has_attached_file-Methode:

    models / book.rb

    URL: "/system/:hash.:extension", hash_secret: "longSecretString"

    Die korrekten Werte werden in die interpoliert url automatisch. hash_secret ist ein Pflichtfeld und der einfachste Weg, es zu erzeugen, ist die Verwendung von:

    Schienen geheim

    Mit Styles arbeiten

    In vielen Fällen ist es bevorzugt, die Miniatur eines Bilds mit vordefinierter Breite und Höhe anzuzeigen, um Bandbreite zu sparen. Paperclip löst dies durch die Verwendung von Stilen: Jeder Stil hat einen Namen und eine Reihe von Regeln wie Abmessungen, Format, Qualität usw.

    Angenommen, wir möchten, dass das Originalbild und die Miniaturansicht in das JPEG-Format konvertiert werden. Die Miniatur sollte auf 300x300px zugeschnitten werden:

    models / book.rb

     has_attached_file: image, styles: thumb: ["300x300 #",: jpeg], original: [: jpeg]

    # ist eine Geometrieeinstellung, die bedeutet: "Zuschneiden, falls erforderlich, während das Seitenverhältnis beibehalten wird."

    Wir können auch zusätzliche Konvertierungsoptionen für jeden Stil bereitstellen. Lassen Sie uns beispielsweise eine 70% -ige Qualität für die Daumen bereitstellen, während Sie alle Metadaten entfernen, und eine 90% -ige Qualität für das Originalbild, um es etwas kleiner zu machen:

    models / book.rb

     has_attached_file: image, styles: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip", original: "-quality 90"

    Nett! Zeigen Sie die Miniaturansicht an und stellen Sie den Link zum Originalbild bereit:

    Ansichten / Bücher / show.html.erb

    <%= link_to(image_tag(@book.image.url(:thumb)), @book.image.url, target: '_blank') if @book.image.exists? %> 

    Beachten Sie, dass Paperclip im Gegensatz zu Carrierwave nicht zum Schreiben berechtigt @ book.image.thumb.url.

    Wenn Sie aus irgendeinem Grund hochgeladene Bilder manuell aktualisieren möchten, können Sie die folgenden Befehle verwenden, um nur Miniaturbilder zu aktualisieren, fehlende Stile hinzuzufügen oder alle Bilder zu aktualisieren:

    • Büroklammer rake: Aktualisieren: Miniaturbilder KLASSE = Buchen
    • Büroklammer rake: refresh: missing_styles CLASS = Buchen
    • Büroklammer rake: Refresh CLASS = Book

    Dateien in der Cloud speichern

    Wie alle ähnlichen Lösungen können Sie mit Paperclip Dateien in die Cloud hochladen. Standardmäßig werden die S3- und Fog-Adapter unterstützt, aber auch Edelsteine ​​von Drittanbietern für Azure und Dropbox. In diesem Abschnitt zeige ich Ihnen, wie Sie Paperclip in Amazon S3 integrieren. Zuerst werfen wir den aws-sdk-Edelstein ab:

    gem 'aws-sdk'

    Es installieren:

    Bundle installieren

    Geben Sie als Nächstes einen neuen Satz von Optionen an has_attached_file Methode:

    models / book.rb

     has_attached_file: image, styles: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip", original: "-quality 90", Speicher :: s3, s3_credentials: access_key_id: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], Bucket: ENV ["S3_BUCKET"], s3_region: ENV ["S3_REGION"]

    Hier halte ich mich an die dotenv-Schienen, um Umgebungsvariablen einzustellen. Sie können alle Werte direkt im Modell angeben, sie jedoch nicht öffentlich verfügbar machen.

    Interessant ist das s3_credentials akzeptiert auch einen Pfad zu einer YAML-Datei, die Ihre Schlüssel und einen Bucket-Namen enthält. Darüber hinaus können Sie verschiedene Werte für verschiedene Umgebungen wie folgt festlegen: 

    Entwicklung: Access_key_id: key1 secret_access_key: secret1 Produktion: access_key_id: key2 secret_access_key: secret2

    Das ist es! Alle Dateien, die Sie hochladen, befinden sich jetzt in Ihrem S3-Bucket.

    Sichern von Dateien in der Cloud

    Angenommen, Sie möchten nicht, dass Ihre hochgeladenen Dateien für jeden verfügbar sind. Standardmäßig werden alle Uploads in die Cloud als öffentlich markiert. Dies bedeutet, dass jeder die Datei über den direkten Link öffnen kann. Wenn Sie eine Berechtigungslogik einführen und prüfen möchten, wer die Datei anzeigen kann, setzen Sie die Option s3_permissions Option zu :Privatgelände so was:

     has_attached_file: image, styles: thumb: ["300x300 #",: jpeg], original: [: jpeg], convert_options: thumb: "-quality 70 -strip", original: "-quality 90", Speicher :: s3, s3_credentials: access_key_id: ENV ["S3_KEY"], secret_access_key: ENV ["S3_SECRET"], Bucket: ENV ["S3_BUCKET"], s3_region: ENV ["S3_REGION"], s3_permissions:: privat

    Nun kann jedoch niemand außer Ihnen die Dateien sehen. Deshalb erstellen wir ein neues herunterladen Aktion für die BooksController:

    books_controller.rb

     def download redirect_to @ book.image.expiring_url end

    Diese Aktion leitet Benutzer einfach über einen auslaufenden Link auf das Bild um. Mit diesem Ansatz können Sie jetzt eine beliebige Berechtigungslogik einführen, die Edelsteine ​​wie CanCanCan oder Pundit verwendet.

    Vergessen Sie nicht, die Mitgliederroute einzustellen:

    config / routes.rb

     Quellen: Bücher erhalten Mitglied "Download" Ende

    Der Helfer sollte folgendermaßen verwendet werden:

    link_to ('Bild anzeigen', download_book_path (@book), Ziel: '_blank')

    Fazit

    Wir sind am Ende dieses Artikels angelangt! Heute haben wir Paperclip, eine Lösung zur Verwaltung von Anhängen von Rails, in Aktion gesehen und deren Hauptkonzepte diskutiert. Dieser Edelstein hat noch viel mehr zu bieten. Sehen Sie sich also die Dokumentation an.

    Ich empfehle außerdem, die Wiki-Seite von Paperclip zu besuchen, da sie eine Liste mit Anleitungen und Anleitungen zu Drittanbieter-Edelsteinen enthält, die Azure und Cloudinary unterstützen und hochgeladene Dateien einfach minimieren können.

    Vielen Dank, dass Sie bei mir geblieben sind, und bis bald!