Advertisement
  1. Code
  2. Ruby on Rails

Hochladen mit Rails und Carrierwave

by
Length:LongLanguages:

German (Deutsch) translation by Władysław Łucyszyn (you can also view the original English article)

Dies ist ein weiterer Artikel in der Reihe "Hochladen mit Schienen". Heute treffen wir Carrierwave - eine der beliebtesten Lösungen zum Hochladen von Dateien für Rails. Ich mag Carrierwave, weil es einfach zu starten ist, viele sofort einsatzbereite Funktionen bietet und Dutzende von "How to" -Artikeln enthält, die von Mitgliedern der Community geschrieben wurden, damit Sie sich nicht verlaufen.

In diesem Artikel erfahren Sie, wie Sie:

  • Carrierwave in Ihre Rails-App integrieren
  • Validierungen hinzufügen
  • Dateien über Anforderungen hinweg beibehalten 
  • Dateien entfernen
  • Miniaturansichten erstellen 
  • Dateien von entfernten Standorten hochladen 
  • mehrere Datei-Uploads einführen 
  • Unterstützung für Cloud-Speicher hinzufügen

Der Quellcode für diesen Artikel ist auf GitHub verfügbar. Viel Spaß beim Lesen!

Grundsteinlegung

Beginnen Sie wie immer mit der Erstellung einer neuen Rails-Anwendung:

Für diese Demo verwende ich Rails 5.0.2. Bitte beachten Sie, dass Carrierwave 1 nur Rails 4+ und Ruby 2 unterstützt. Wenn Sie noch auf Rails 3 fahren, schließen Sie Carrierwave Version 0.11 an.

Um Carrierwave in Aktion zu sehen, erstellen wir eine sehr einfache Blogging-Anwendung mit einem einzigen Post-Modell. Es wird die folgenden Hauptattribute haben:

  • title (string)
  • body (text)
  • image (string) - Dieses Feld enthält ein Bild (genauer gesagt den Namen einer Datei), das an den Beitrag angehängt ist

Generieren und Anwenden einer neuen Migration:

Richten Sie einige Routen ein:

config/routes.rb

Erstellen Sie außerdem einen sehr einfachen Controller:

posts_controller.rb

Nun erstellen wir die index-Ansicht:

views/posts/index.html.erb

Und der entsprechende Teil:

views/posts/_post.html.erb

Hier verwende ich die Rails truncate-Methode, um nur die ersten 150 Symbole aus dem Beitrag anzuzeigen. Bevor wir andere Ansichten und einen Teil des Formulars erstellen, integrieren wir zunächst Carrierwave in die Anwendung.

Carrierwave integrieren

Legen Sie einen neuen Edelstein in die Gemfile:

Gemfile

Lauf:

Carrierwave speichert seine Konfiguration in Uploadern, die in Ihren Modellen enthalten sind. Verwenden Sie den folgenden Befehl, um einen Uploader zu generieren:

In app/uploaders finden Sie jetzt eine neue Datei mit dem Namen image_uploader.rb. Beachten Sie, dass es einige nützliche Kommentare und Beispiele enthält, sodass Sie es verwenden können, um loszulegen. In dieser Demo werden wir ActiveRecord verwenden, aber Carrierwave unterstützt auch Mongoid, Sequel und DataMapper.

Als nächstes müssen wir diesen Uploader in das Modell aufnehmen oder einbinden:

models/post.rb

Der Uploader hat bereits vernünftige Standardeinstellungen, aber zumindest müssen wir auswählen, wo die hochgeladenen Dateien gespeichert werden sollen. Lassen Sie uns zunächst den Dateispeicher verwenden:

uploaders/image_uploader.rb

Standardmäßig werden Dateien im Verzeichnis public/uploads abgelegt. Schließen Sie sie daher am besten aus dem Versionskontrollsystem aus:

.gitignore

Sie können auch die store_dir-Methode in Ihrem Uploader ändern, um einen anderen Speicherort auszuwählen.

Zu diesem Zeitpunkt können wir eine neue Ansicht und ein Teilformular erstellen, um mit dem Hochladen von Dateien zu beginnen:

views/posts/new.html.erb

views/posts/_form.html.erb

Beachten Sie, dass der PostsController nicht geändert werden muss, da wir das image-Attribut bereits zugelassen haben.

Zuletzt erstellen Sie die Bearbeitungsansicht:

views/posts/edit.html.erb

Das ist es! Sie können den Server starten und versuchen, einen Beitrag mit einem Image zu erstellen. Das Problem ist, dass dieses Bild nirgendwo sichtbar ist. Fahren wir also mit dem nächsten Abschnitt fort und fügen Sie eine Show-Seite hinzu!

Bilder anzeigen

Die einzige Ansicht, die wir noch nicht erstellt haben, ist show. Jetzt hinzufügen:

views/posts/show.html.erb

Wie Sie sehen, ist das Anzeigen eines Anhangs sehr einfach: Sie müssen lediglich @post.image.url sagen, um die URL eines Bildes abzurufen. Verwenden Sie die Methode current_path, um einen Pfad zur Datei abzurufen. Beachten Sie, dass Carrierwave auch ein liefert image? Methode, mit der wir überprüfen können, ob überhaupt ein Anhang vorhanden ist (die image-Methode selbst gibt niemals nil zurück, selbst wenn die Datei nicht vorhanden ist).

Nachdem Sie zu einem Beitrag navigiert haben, sollte ein Bild angezeigt werden, das jedoch möglicherweise zu groß erscheint. Schließlich beschränken wir die Abmessungen nirgendwo. Natürlich hätten wir das Bild mit einigen CSS-Regeln verkleinern können, aber es ist viel besser, nach dem Hochladen der Datei eine Miniaturansicht zu erstellen. Dies erfordert jedoch einige zusätzliche Schritte.

Thumbnails generieren

Zum Zuschneiden und Skalieren von Bildern benötigen wir ein separates Werkzeug. Im Lieferumfang von Carrierwave sind RMagick- und MiniMagick-Edelsteine enthalten, mit denen Bilder mithilfe von ImageMagick bearbeitet werden können. ImageMagick ist eine Open-Source-Lösung, mit der Sie vorhandene Bilder bearbeiten und neue generieren können. Bevor Sie fortfahren, müssen Sie sie herunterladen und installieren. Als nächstes können Sie einen der beiden Edelsteine auswählen. Ich bleibe bei MiniMagick, weil es viel einfacher zu installieren ist und eine bessere Unterstützung bietet:

Gemfile

Lauf:

Fügen Sie dann MiniMagick in Ihren Uploader ein:

uploaders/image_uploader.rb

Jetzt müssen wir nur noch eine neue Version für unseren Uploader einführen. Das Konzept von Versionen (oder Stilen) wird in vielen Dateien zum Hochladen von Dateien verwendet. Dies bedeutet lediglich, dass zusätzliche Dateien basierend auf dem ursprünglichen Anhang beispielsweise mit unterschiedlichen Abmessungen oder Formaten erstellt werden. Stellen Sie eine neue Version mit dem Namen thumb vor:

uploaders/image_uploader.rb

Möglicherweise haben Sie so viele Versionen, wie Sie möchten, und außerdem können Versionen sogar auf anderen Versionen erstellt werden:

uploaders/image_uploader.rb

Wenn Sie bereits einige Bilder hochgeladen haben, sind keine Miniaturansichten verfügbar. Dies ist jedoch kein Problem, da Sie sie über die Rails-Konsole neu erstellen können:

Zuletzt zeigen Sie Ihr Miniaturbild mit einem Link zum Originalbild an:

views/posts/show.html.erb

Starten Sie den Server und beobachten Sie das Ergebnis!

Validierungen hinzufügen

Derzeit funktioniert unser Upload, aber wir validieren überhaupt keine Benutzereingaben, was natürlich schlecht ist. Solange wir nur mit Bildern arbeiten möchten, lassen Sie uns die Erweiterungen .png, .jpg und .gif auf die Whitelist setzen:

uploaders/image_uploader.rb

Sie können auch Inhaltstypprüfungen hinzufügen, indem Sie eine content_type_whitelist-Methode definieren:

uploaders/image_uploader.rb

Alternativ ist es möglich, einige Dateitypen, z. B. ausführbare Dateien, durch Definieren der Methode content_type_blacklist auf eine schwarze Liste zu setzen.

Lassen Sie uns nicht nur den Dateityp und die Dateierweiterung überprüfen, sondern auch einen Wert von weniger als 1 Megabyte festlegen. Dazu benötigen wir ein zusätzliches gem, das die Dateiprüfungen für ActiveModel unterstützt:

Gemfile

Es installieren:

Führen Sie nun die gewünschten Validierungen ein (beachten Sie, dass ich auch Überprüfungen für die title- und body-Attribute hinzufüge):

models/post.rb

Als Nächstes müssen I18n-Übersetzungen für die Fehlermeldungen von Carrierwave hinzugefügt werden:

config/locales/en.yml

Derzeit werden nirgendwo Validierungsfehler angezeigt. Erstellen wir daher einen gemeinsamen Teil:

views/shared/_errors.html.erb

Verwenden Sie diesen Teil innerhalb des Formulars:

views/posts/_form.html.erb

Versuchen Sie nun, einige ungültige Dateien hochzuladen und das Ergebnis zu beobachten. Es sollte funktionieren, aber wenn Sie eine gültige Datei auswählen und den Titel oder Text nicht eingeben, schlagen die Überprüfungen immer noch fehl und es wird ein Fehler angezeigt. Das Dateifeld wird jedoch gelöscht und der Benutzer muss das Bild erneut auswählen, was nicht sehr praktisch ist. Um dies zu beheben, müssen wir dem Formular ein weiteres Feld hinzufügen.

Persistierende Dateien über Anfragen hinweg

Das Fortbestehen von Dateien über Formular-Redisplays hinweg ist eigentlich recht einfach. Sie müssen lediglich ein neues verstecktes Feld hinzufügen und es im Controller zulassen:

views/shared/_form.html.erb

posts_controller.rb

Jetzt wird der image_cache automatisch gefüllt und das Bild geht nicht verloren. Es kann hilfreich sein, auch eine Miniaturansicht anzuzeigen, damit der Benutzer versteht, dass das Bild erfolgreich verarbeitet wurde:

views/shared/_form.html.erb

Bilder entfernen

Eine weitere sehr häufige Funktion ist die Möglichkeit, angehängte Dateien beim Bearbeiten eines Datensatzes zu entfernen. Mit Carrierwave ist die Implementierung dieser Funktion kein Problem. Fügen Sie dem Formular ein neues Kontrollkästchen hinzu:

views/shared/_form.html.erb

Und erlauben Sie das Attribut remove_image:

posts_controller.rb

Das ist es! Verwenden Sie zum manuellen Entfernen eines Bildes das remove_image! Methode:

Hochladen von einem entfernten Standort

Carrierwave bietet auch eine sehr coole sofort einsatzbereite Funktion: die Möglichkeit, Dateien von entfernten Standorten über deren URL hochzuladen. Lassen Sie uns diese Fähigkeit jetzt einführen, indem Sie ein neues Feld hinzufügen und das entsprechende Attribut zulassen:

views/shared/_form.html.erb

posts_controller.rb

Wie cool ist das? Sie müssen überhaupt keine Änderungen vornehmen und können diese Funktion sofort testen!

Arbeiten mit mehreren Uploads

Angenommen, wir möchten, dass in unserem Beitrag mehrere Anhänge verfügbar sind. Mit dem aktuellen Setup ist dies nicht möglich, aber zum Glück unterstützt Carrierwave auch ein solches Szenario. Um diese Funktion zu implementieren, müssen Sie entweder ein serialisiertes Feld (für SQLite) oder ein JSON-Feld (für Postgres oder MySQL) hinzufügen. Ich bevorzuge die letztere Option, also wechseln wir jetzt zu einem neuen Datenbankadapter. Entfernen Sie den sqlite3-Edelstein aus der Gemfile und fügen Sie stattdessen pg hinzu:

Gemfile

Es installieren:

Ändern Sie die Datenbankkonfiguration wie folgt:

config/database.yml

Erstellen Sie die entsprechende Postgres-Datenbank, generieren Sie die Migration und wenden Sie sie an:

Wenn Sie lieber bei SQLite bleiben möchten, befolgen Sie die Anweisungen in der Dokumentation von Carrierwave.

Montieren Sie nun die Uploader (beachten Sie die Pluralform!):

model/post.rb

Ich verwende denselben Uploader für Anhänge, aber Sie können natürlich einen neuen mit einer anderen Konfiguration generieren.

Fügen Sie Ihrem Formular das Feld mit mehreren Dateien hinzu:

views/shared/_form.html.erb

Solange das Feld attachments ein Array enthalten soll, sollte dies folgendermaßen zulässig sein:

posts_controller.rb

Zuletzt können Sie die Anhänge des Beitrags durchlaufen und wie gewohnt anzeigen:

views/shared/show.html.erb

Beachten Sie, dass für jeden Anhang eine Miniaturansicht vorhanden ist, wie in unserem ImageUploader konfiguriert. Nett!

Cloud-Speicher verwenden

Das Festhalten am Dateispeicher ist nicht immer bequem und / oder möglich, da beispielsweise auf Heroku keine benutzerdefinierten Dateien gespeichert werden können. Daher könnten Sie sich fragen, wie Sie Carrierwave mit Amazon S3 Cloud Storage heiraten können. Nun, das ist auch eine ziemlich einfache Aufgabe. Carrierwave hängt von der fog-aws gem ab, um diese Funktion zu implementieren:

Gemfile

Es installieren:

Erstellen wir einen Initialisierer für Carrierwave und konfigurieren Sie den Cloud-Speicher global:

config/initializers/carrierwave.rb

Es stehen einige andere Optionen zur Verfügung, die Sie in der Dokumentation finden.

Ich verwende das dotenv-Rails gem, um die Umgebungsvariablen auf sichere Weise festzulegen, aber Sie können eine andere Option auswählen. Stellen Sie jedoch sicher, dass Ihr S3-Schlüsselpaar nicht öffentlich verfügbar ist, da sonst jeder etwas in Ihren Bucket hochladen kann!

Ersetzen Sie als Nächstes die Zeile storage :file durch:

uploaders/image_uploader.rb

Abgesehen von S3 unterstützt Carrierwave Uploads zu Google Storage und Rackspace. Diese Dienste sind ebenfalls einfach einzurichten.

Abschluss

Das ist es für heute! Wir haben alle wichtigen Funktionen von Carrierwave behandelt, und jetzt können Sie es in Ihren Projekten verwenden. Es stehen einige zusätzliche Optionen zur Verfügung. Durchsuchen Sie daher die Dokumentation.

Wenn Sie nicht weiterkommen, zögern Sie nicht, Ihre Fragen zu stellen. Es kann auch nützlich sein, einen Blick in das Carrierwave-Wiki zu werfen, das nützliche Anleitungen enthält, in denen viele häufig gestellte Fragen beantwortet werden.

Ich danke Ihnen, dass Sie bei mir geblieben sind und viel Spaß beim Codieren haben!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.