So laden Sie Dateien mit DragonFly einfach hoch

Das Hochladen von Dateien ist im Allgemeinen ein schwieriger Bereich in der Webentwicklung. In diesem Lernprogramm erfahren Sie, wie Sie Dragonfly verwenden, einen leistungsstarken Ruby-Edelstein, mit dem Sie einfach und effizient beliebige Upload-Funktionen zu einem Rails-Projekt hinzufügen können.


Was wir bauen werden

In unserer Beispielanwendung wird eine Liste der Benutzer angezeigt. Für jeden Benutzer können wir einen Avatar hochladen und speichern lassen. Zusätzlich erlaubt uns Dragonfly:

  • Bilder können dynamisch bearbeitet werden, ohne zusätzliche Kopien zu speichern
  • Nutzen Sie das HTTP-Caching, um die Anwendungslast zu optimieren

In dieser Lektion folgen wir einem BDD-Ansatz (Behavior Driven Development) mit Gurke und RSpec.


Voraussetzungen

Sie müssen Imagemagick installiert haben: Auf dieser Seite finden Sie die Binärdateien, die installiert werden sollen. Da ich auf einer Mac-Plattform arbeite, verwende Homebrew, ich kann einfach tippen brauen installieren imagemagick.

Sie müssen auch eine grundlegende Rails-Anwendung klonen, die wir als Ausgangspunkt verwenden werden.


Konfiguration

Wir beginnen mit dem Klonen des Start-Repositorys und dem Einrichten unserer Abhängigkeiten:

git clone http: //[email protected]/cloud8421/tutorial_dragonfly_template.git cd tutorial_dragonfly_template

Für diese Anwendung muss mindestens Ruby 1.9.2 ausgeführt werden. Ich empfehle Ihnen jedoch, 1.9.3 zu verwenden. Die Rails-Version ist 3.2.1. Das Projekt enthält keine .rvmrc oder ein .Rbenv Datei.

Als nächstes laufen wir:

Bundle Install Bundle Exec Rake Db: Setup Db: Test: Vorbereiten Db: Seed

Dies kümmert sich um die Abhängigkeiten der Edelsteine ​​und die Einrichtung der Datenbank (wir werden sqlite verwenden, sodass Sie sich keine Sorgen um die Datenbankkonfiguration machen müssen)..

Um zu testen, dass alles wie erwartet funktioniert, können wir Folgendes ausführen:

Bündel Exec Rspec Bündel Exec Gurke

Sie sollten feststellen, dass alle Tests bestanden sind. Sehen wir uns die Ausgabe von Cucumber an:

 Feature: Benutzerprofil verwalten Als Benutzer Um meine Daten zu verwalten, möchte ich auf meine Benutzerprofilseite zugreifen. Hintergrund: Wenn ein Benutzer mit der E-Mail "[email protected]" vorhanden ist Szenario: Anzeigen meines Profils Gegeben, ich befinde mich auf der Startseite Wann Ich folge "Profil" für "[email protected]" Dann sollte ich auf der Profilseite für "[email protected]" sein Szenario: Profil bearbeiten Gegeben, ich bin auf der Profilseite für "[email protected]", wenn Ich folge "Bearbeiten" und ändere meine E-Mail mit "[email protected]". Und ich klicke auf "Speichern". Dann sollte ich auf der Profilseite für "[email protected]" sein. Ich sollte "Benutzer aktualisiert" 2 Szenarien sehen (2 bestanden) 11 Schritte (11 bestanden) 0m0.710s

Wie Sie sehen, beschreiben diese Funktionen einen typischen Benutzerworkflow: Wir öffnen eine Benutzerseite aus einer Liste und klicken auf "Bearbeiten", um die Benutzerdaten zu bearbeiten, die E-Mail zu ändern und zu speichern.

Versuchen Sie jetzt, die App auszuführen:

Schienen s

Wenn du öffnest http :: // localhost: 3000 Im Browser finden Sie eine Benutzerliste (die Datenbank wurde dank Faker-Gem mit 40 zufälligen Datensätzen vorbelegt)..

Im Moment hat jeder Benutzer einen kleinen 16x16px-Avatar und einen großen Platzhalter-Avatar in seiner Profilseite. Wenn Sie den Benutzer bearbeiten, können Sie dessen Details (Vorname, Nachname und Kennwort) ändern. Wenn Sie jedoch versuchen, einen Avatar hochzuladen, wird dieser nicht gespeichert.

Gerne können Sie die Codebasis durchsuchen: Die Anwendung verwendet Simple Form, um Formularansichten und Twitter Bootstrap für CSS und Layout zu generieren, da sie perfekt integriert sind und den Prototyping-Prozess beschleunigen.


Funktionen für den Avatar-Upload

Wir beginnen mit dem Hinzufügen eines neuen Szenarios zu features / manage_profile.feature:

… Szenario: Hinzufügen eines Avatars Gegeben ich bin auf der Profilseite für "[email protected]" Wenn ich "Bearbeiten" folge Und ich den Schnurrbart-Avatar hochlade Und ich auf "Speichern" klicke. Dann sollte ich auf der Profilseite für "E-Mail" sein @ example.com "Und das Profil sollte" den Schnurrbart-Avatar "zeigen

Diese Funktion ist ziemlich selbsterklärend, erfordert jedoch einige zusätzliche Schritte features / step_definitions / user_steps.rb:

… Wenn / ^ ich den Schnurrbart-Avatar hochlade $ / do attach_file 'user [avatar_image]', Rails.root + 'spec / fixtures / moustache_avatar.jpg' end Dann / ^ sollte das Profil "([^"] *) "anzeigen. $ / do | image | pattern = Fallbild, wenn "der Schnurrbart-Avatar" / moustache_avatar / end n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']") .stirst ['src']. sollte = ~ Musterende sein

Dieser Schritt setzt voraus, dass Sie ein Bild haben, das aufgerufen wird moustache_avatar.jpg Innerhalb Spec / Fixtures. Wie Sie sich vorstellen können, ist dies nur ein Beispiel. es kann alles sein, was du willst.

Der erste Schritt verwendet Capybara, um die Benutzer [avatar_image] Dateifeld und laden Sie die Datei hoch. Beachten Sie, dass wir davon ausgehen, dass wir eine a haben werden avatar_image Attribut auf die Nutzer Modell-.

Der zweite Schritt verwendet Nokogiri (eine leistungsstarke HTML / XML-Parsing-Bibliothek) und XPath, um den Inhalt der resultierenden Profilseite zu analysieren und nach der ersten zu suchen img tag mit einem Miniaturansicht klasse und teste das src Attribut enthält moustache_avatar.

Wenn du läufst Gurke Dieses Szenario löst jetzt einen Fehler aus, da kein Dateifeld mit dem von uns angegebenen Namen vorhanden ist. Es ist jetzt an der Zeit, sich auf das Thema zu konzentrieren Nutzer Modell-.


Dragonfly-Unterstützung zum Benutzermodell hinzufügen

Vor der Integration von Dragonfly mit der Nutzer Modell, lassen Sie uns ein paar Spezifikationen hinzufügen user_spec.rb.

Wir können einen neuen Block direkt nach dem einfügen Attribute Kontext:

 Kontext "Avatar-Attribute" do it sollte answer_to (: avatar_image) soll allow_mass_assignment_of (: avatar_image) enden

Wir testen, dass der Nutzer eine avatar_image Attribut und da dieses Attribut durch ein Formular aktualisiert wird, muss es zugänglich sein (zweite Spezifikation).

Jetzt können wir Dragonfly installieren: Auf diese Weise werden diese Spezifikationen grün.

Fügen wir der Gemfile folgende Zeilen hinzu:

 gem 'rack-cache', erfordert: 'rack / cache' gem 'libelle', '~> 0.9.10'

Als nächstes können wir rennen Bundle installieren. Rack-Cache wird in der Entwicklung benötigt, da dies die einfachste Option für das HTTP-Caching ist. Es kann auch in der Produktion eingesetzt werden, auch wenn robustere Lösungen (wie Lack oder Tintenfisch) besser sind.

Wir müssen auch den Dragonfly-Initialisierer hinzufügen. Lass uns die erstellen config / initializers / dragonfly.rb Datei und fügen Sie Folgendes hinzu:

 "dragonfly" app = Dragonfly [: images] app.configure_with (: imagemagick) app.configure_with (: schienen) app.define_macro (ActiveRecord :: Base,: image_accessor)

Dies ist die Vanilla Dragonfly-Konfiguration: Sie richtet eine Dragonfly-Anwendung ein und konfiguriert sie mit dem benötigten Modul. Außerdem wird ein neues Makro hinzugefügt Aktiver Rekord dass wir in der Lage sein werden, unsere zu erweitern Nutzer Modell-.

Wir müssen aktualisieren config / application.rb, und fügen Sie der Konfiguration eine neue Direktive hinzu (direkt vor dem config.generators Block):

 config.middleware.insert 0, 'Rack :: Cache', Verbose: true, Metastore: URI.encode ("file: # Rails.root / tmp / dragonfly / cache / meta"), entitystore: URI.encode ("file: # Rails.root / tmp / libelle / cache / body")) sofern nicht Rails.env.production? config.middleware.insert_after 'Rack :: Cache', 'Dragonfly :: Middleware': Bilder

Ohne viel ins Detail zu gehen, richten wir uns ein Rack :: Cache (außer für die Produktion, wo es standardmäßig aktiviert ist) und das Einrichten von Dragonfly für dessen Verwendung.

Wir speichern unsere Bilder auf der Festplatte, benötigen jedoch eine Möglichkeit, die Zuordnung zu einem Benutzer zu verfolgen. Die einfachste Option besteht darin, der Benutzertabelle bei einer Migration zwei Spalten hinzuzufügen:

Schienen g Migration add_avatar_to_users avatar_image_uid: Zeichenfolge avatar_image_name: Zeichenfolge Bündel Exec Rake Datenbank: Migrieren Datenbank: Test: Vorbereiten

Dies ist wiederum direkt aus der Dokumentation von Dragonfly: Wir brauchen eine avatar_image_uid Spalte, um die Avatar-Datei eindeutig zu identifizieren, und a avatar_image_name um den ursprünglichen Dateinamen zu speichern (die letzte Spalte ist nicht unbedingt erforderlich, ermöglicht jedoch die Erzeugung von Bild-URLs, die mit dem ursprünglichen Dateinamen enden).

Zum Schluss können wir das aktualisieren Nutzer Modell:

 Klasse Benutzer < ActiveRecord::Base image_accessor :avatar_image attr_accessible :email, :first_name, :last_name, :avatar_image… 

Das image_accessor Diese Methode wird vom Dragonfly-Initialisierer zur Verfügung gestellt und erfordert nur einen Attributnamen. Wir machen dasselbe Attribut auch in der Zeile darunter zugänglich.

Laufen rspec sollte jetzt alle Angaben grün zeigen.


Avatar hochladen und anzeigen


Um die Upload-Funktion zu testen, können Sie einen Kontext hinzufügen users_controller_spec.rb in dem PUT-Update Block:

 Kontext "Avatar-Bild" lassen Sie sich! (: Bilddatei) fixture_file_upload ('/ mustache_avatar.jpg', 'image / jpg') Kontext "Hochladen eines Avatars" vor dem Einfügen: update, id: user.id, Benutzer: avatar_image: image_file end es "sollte den Image-Datensatz effektiv auf dem Benutzer speichern" do user.avatar_image_name.should = ~ / moustache_avatar / end end end

Wir werden das gleiche Gerät wiederverwenden und ein Mock für den Upload mit erstellen fixture_file_upload.

Da diese Funktionalität für Dragonfly genutzt wird, müssen wir keinen Code schreiben, um ihn zu übergeben.

Wir müssen jetzt unsere Ansichten aktualisieren, um den Avatar zu zeigen. Beginnen wir mit der Benutzershow-Seite und öffnen Sie sie app / views / users / show.html.erb und aktualisieren Sie es mit folgendem Inhalt:

 
<% if @user.avatar_image.present? %> <%= image_tag @user.avatar_image.url, class: 'thumbnail' %> <% else %> Super cooler Avatar <% end %>

<%= @user.name %>

<%= @user.email %>


<%= link_to 'Edit', edit_user_path(@user), class: "btn" %>

Als nächstes können wir aktualisieren app / views / users / edit.html.erb:

 <%= simple_form_for @user, multipart: true do |f| %> 
<% if @user.avatar_image.present? %> <%= image_tag @user.avatar_image.url, class: 'thumbnail' %> <% else %> Super cooler Avatar <% end %>
<%= f.input :avatar_image, as: :file %>
<%= f.input :first_name %> <%= f.input :last_name %> <%= f.input :email %>
<%= f.submit 'Save', class: "btn btn-primary" %>
<% end %>

Wir können den Benutzeravatar mit einem einfachen Anruf an zeigen @ user.avatar_image.url. Dadurch wird eine URL zu einer nicht geänderten Version des vom Benutzer hochgeladenen Avatars zurückgegeben.

Wenn du läufst Gurke Jetzt sehen Sie die grüne Funktion. Probieren Sie es auch im Browser aus!

Wir verlassen uns implizit auf CSS, um die Größe des Bildes zu ändern, wenn es für den Container zu groß ist. Es ist ein wackeliger Ansatz: Unser Benutzer könnte nicht quadratische Avatare oder ein sehr kleines Bild hochladen. Außerdem liefern wir immer dasselbe Bild, ohne sich um Seitengröße oder Bandbreite zu kümmern.

Wir müssen in zwei verschiedenen Bereichen arbeiten: Hinzufügen von Validierungsregeln zum Avatar-Upload und Festlegen der Bildgröße und des Bildverhältnisses mit Dragonfly.


Validierungen hochladen

Wir beginnen mit dem Öffnen der user_spec.rb Datei und Hinzufügen eines neuen Spezifikationsblocks:

 Kontext "Avatar-Attribute" do% w (avatar_image preserv_avatar_image remove_avatar_image) .each do | attr | it sollte_antworten (attr.to_sym) end% w (avatar_image preserv_avatar_image remove_avatar_image) .each do | attr | es sollte allow_mass_assignment_of (attr.to_sym) enden. es sollte "die Dateigröße des Avatars überprüfen" "do user.avatar_image = Rails.root + 'spec / fixtures / huge_size_avatar.jpg' user.should_not be_valid # size> 100 KB end es "sollte das Format des Avatars validieren" do user.avatar_image = Rails.root + 'spec / fixtures / dummy.txt' user.should_not ist kein Ende

Wir testen auf Anwesenheit und erlauben "Massenzuordnung" für zusätzliche Attribute, die wir zur Verbesserung des Benutzerformulars verwenden werden (: retention_avatar_image und : remove_avatar_image).

Darüber hinaus testen wir auch, dass unser Benutzermodell keine großen Uploads (mehr als 200 KB) und Dateien akzeptiert, die keine Bilder sind. In beiden Fällen müssen wir zwei Fixture-Dateien hinzufügen (ein Bild mit dem angegebenen Namen und einer Größe von mehr als 200 KB und eine Textdatei mit beliebigem Inhalt)..

Wie üblich führt uns das Ausführen dieser Daten nicht zum Grün. Lassen Sie uns das Benutzermodell aktualisieren, um diese Validierungsregeln hinzuzufügen:

… Attr_accessible: email,: first_name,: last_name,: avatar_image,: retention_avatar_image,: remove_avatar_image… validates_size_of: avatar_image, maximal: 100.kilobytes validates_property: format, of:: avatar_image, in: [: jpeg,: : jpg] validates_property: mime_type, of:: avatar_image, in: ['image / jpg', 'image / jpeg', 'image / png', 'image / gif'], case_sensitive: false

Diese Regeln sind ziemlich effektiv: Beachten Sie, dass wir nicht nur das Format überprüfen, sondern auch den Mime-Typ auf Sicherheit prüfen. Als Bild erlauben wir jpg-, png- und gif-Dateien.

Unsere Spezifikationen sollten jetzt vergangen sein. Daher ist es an der Zeit, die Ansichten zu aktualisieren, um die Bildlast zu optimieren.


Dynamische Bildverarbeitung

Standardmäßig verwendet Dragonfly ImageMagick, um Bilder dynamisch zu verarbeiten, wenn Sie dazu aufgefordert werden. Angenommen, wir haben eine Nutzer In einer unserer Ansichten könnten wir dann:

 user.avatar_image.thumb ('100x100'). url user.avatar_image.process (: greyscale) .url

Diese Methoden erstellen eine verarbeitete Version dieses Bildes mit einem eindeutigen Hash, und dank unserer Caching-Ebene wird ImageMagick nur einmal pro Bild aufgerufen. Danach wird das Bild direkt aus dem Cache geliefert.

Sie können viele integrierte Methoden verwenden oder einfach Ihre eigenen erstellen. Die Dokumentation von Dragonfly enthält viele Beispiele.

Lassen Sie uns unseren Benutzer noch einmal besuchen bearbeiten Seite und aktualisieren Sie den Ansichtscode:

… <% if @user.avatar_image.present? %> <%= image_tag @user.avatar_image.thumb('400x400#').url, class: 'thumbnail' %> <% else %>… 

Wir machen das gleiche für den Benutzer Show Seite:

… <% if @user.avatar_image.present? %> <%= image_tag @user.avatar_image.thumb('400x400#').url, class: 'thumbnail' %> <% else %>… 

Wir legen die Bildgröße auf 400 x 400 Pixel fest. Das # Der Parameter weist ImageMagick außerdem an, das Bild unter Beibehaltung der zentralen Schwerkraft zu beschneiden. Sie können sehen, dass wir denselben Code an zwei Stellen haben, also lassen Sie uns dies in einen partiellen Aufruf umwandeln Ansichten / Benutzer / _avatar_image.html.erb

 <% if @user.avatar_image.present? %> <%= image_tag @user.avatar_image.thumb('400x400#').url, class: 'thumbnail' %> <% else %> Super cooler Avatar <% end %>

Dann können wir den Inhalt von ersetzen .Miniaturansicht Container mit einem einfachen Aufruf an:

 
<%= render 'avatar_image' %>

Wir können es noch besser machen, indem wir das Argument von verschieben Daumen aus dem partiellen. Lassen Sie uns aktualisieren _avatar_image.html.erb:

 <% if user.avatar_image.present? %> <%= image_tag user.avatar_image.thumb(args).url %> <% else %> & text = Super + cool + avatar "alt =" Super cooler Avatar "> <% end %>

Wir können unser Partial mit zwei Argumenten aufrufen: eines für den gewünschten Aspekt und eines für den Benutzer:

 <%= render 'avatar_image', args: '400x400#', user: @user %>

Wir können den obigen Ausschnitt in verwenden bearbeiten und Show Ansichten, während wir es auf folgende Weise innen nennen können Ansichten / Benutzer / _user_table.html.erb, Wo zeigen wir die kleinen Thumbnails.

… <%= link_to 'Profile', user_path(user) %>  <%= render 'avatar_image', args: '16x16#', user: user %>  <%= user.first_name %>… 

In beiden Fällen führen wir auch eine Regex-Funktion für den Aspekt aus, um eine mit dem placehold.it-Dienst kompatible Zeichenfolge zu extrahieren (d. H. Nicht alphanumerische Zeichen zu entfernen)..


Den Avatar entfernen


Dragonfly erstellt zwei zusätzliche Attribute, die wir in einem Formular verwenden können:

  • retention_avatar_image: speichert das hochgeladene Bild zwischen den Neuladevorgängen. Wenn Validierungen für ein anderes Formularfeld (z. B. E-Mail) fehlschlagen und die Seite erneut geladen wird, ist das hochgeladene Bild weiterhin verfügbar, ohne dass es erneut hochgeladen werden muss. Wir werden es direkt im Formular verwenden.
  • remove_avatar_image: Wenn dies zutrifft, wird das aktuelle Avatar-Bild sowohl vom Benutzerdatensatz als auch vom Datenträger gelöscht.

Wir können die Entfernung des Avatars testen, indem Sie eine zusätzliche Spezifikation hinzufügen users_controller_spec.rb, in dem Avatar-Bild Block:

… Kontext "Entfernen eines Avatars" vor dem Ausführen von user.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' user.save ende es "sollte den Avatar vom Benutzer entfernen": put, update, id: user. id, benutzer: remove_avatar_image: "1" user.reload user.avatar_image_name.should be_nil end end… 

Wieder wird Dragonfly diese Spezifikation automatisch erhalten lassen, da wir bereits die haben remove_avatar_image Attribut für die Benutzerinstanz verfügbar.

Fügen wir dann eine weitere Funktion hinzu Managing_profile.feature:

 Szenario: Entfernen eines Avatars Angesichts des Benutzers mit der E-Mail "[email protected]" hat der Schnurrbart-Avatar. Ich bin auf der Profilseite für "[email protected]", wenn ich "Bearbeiten" folge. Und ich klicke auf "Speichern". Dann sollte ich auf der Profilseite für "[email protected]" sein. Das Profil sollte "den Platzhalter-Avatar" anzeigen.

Wie üblich müssen wir einige Schritte hinzufügen user_steps.rb und aktualisieren, um einen Regex für den Platzhalter-Avatar hinzuzufügen:

 Der Benutzer mit der E-Mail-Adresse "([^"] *) hat / / den Schnurrbart-Avatar $ / do | email | u = User.find_by_email (email) u.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg 'u.save end Wenn / ^ ich "([^"] *) "$ / do | checkbox | check checkbox end Dann / ^ sollte das Profil "([^"] *) "$ / do | image | pattern = case image anzeigen, wenn" der Platzhalter-Avatar "/placehold.it/ ist, wenn" der Schnurrbart-Avatar "/ mustache_avatar / end ist n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). first ['src']. sollte = ~ Musterende

Wir müssen auch zwei zusätzliche Felder zum hinzufügen bearbeiten bilden:

<%= f.input :retained_avatar_image, as: :hidden %> <%= f.input :avatar_image, as: :file, label: false %> <%= f.input :remove_avatar_image, as: :boolean %>

Dadurch wird unser Feature bestanden.


Refactoring-Funktionen

Um ein großes und zu detailliertes Feature zu vermeiden, können wir dieselbe Funktionalität in einer Anforderungsspezifikation testen.

Erstellen wir eine neue Datei mit dem Namen spec / request / user_flow_spec.rb und fügen Sie diesen Inhalt hinzu:

 erfordern 'spec_helper' beschreiben "Benutzerablauf" do let! (: Benutzer) Factory (: Benutzer, E-Mail: "[email protected]") beschreiben "Anzeigen des Profils" do it "sollte das Profil für den Benutzer anzeigen" Besuchen Sie '/' page.find ('tr', Text: user.email) .click_link ("Profile") current_path = URI.parse (current_url) .path current_path.should == user_path (user) end end beschreiben die Aktualisierung Profildaten "do it" sollten die Änderungen speichern "do visit '/' page.find ('tr', Text: user.email) .click_link (" Profile ") click_link 'Edit' fill_in: email, mit:" new_email @ example.com "click_button" Save "current_path.should == user_path (user) page.should have_content" Benutzer aktualisiert "end end beschreiben" Avatar verwalten "do it" sollte den hochgeladenen Avatar speichern "do user.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' user.save visit user_path (user) click_link 'Edit' attach_file 'user [avatar_image]', Rails.root + 'spec / fixtures / mustache_avatar.jpg' click_button 'Speichern' current_path.hould == user_path (user) page.hould_con haben Zelt "Benutzer aktualisiert" n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). first ['src']. sollte = ~ / mustache_avatar / end "sollte der Avatar entfernt werden, wenn er angefordert wird" do user.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' user.save visit user_path (Benutzer) click_link 'Edit' check 'Remove avatar image' click_button 'Save' current_path .should == user_path (user) page.should have_content "Benutzer aktualisiert" n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). first [' src ']. sollte = ~ /placehold.it/ end end end

Die Spezifikation umfasst alle Schritte, die wir zur Definition unseres Hauptmerkmals verwendet haben. Das Markup und der Fluss werden gründlich getestet, sodass wir sicherstellen können, dass alles auf granularer Ebene einwandfrei funktioniert.

Jetzt können wir das kürzen Managing_profile.feature:

 Feature: Benutzerprofil verwalten Als Benutzer Um meine Daten zu verwalten, möchte ich auf meine Benutzerprofilseite zugreifen. Hintergrund: Wenn ein Benutzer mit der E-Mail "[email protected]" vorhanden ist Szenario: Profil bearbeiten Gegeben, ich ändere die E-Mail mit "new_mail" @ example.com "für" [email protected] "Dann sollte ich" Benutzer aktualisiert "sehen. Szenario: Hinzufügen eines Avatars Gegebenfalls lade ich den Schnurrbart-Avatar für" [email protected] "hoch. Dann sollte das Profil" Der Schnurrbart-Avatar "anzeigen. Szenario: Entfernen eines Avatars Gegeben der Benutzer "[email protected]" hat den Schnurrbart-Avatar und ich entferne ihn. Dann sollte der Benutzer "[email protected]" "den Platzhalter-Avatar" haben.

Aktualisierte user_steps.rb:

 Gegeben / ^ Ein Benutzer existiert mit der E-Mail "([^"] *) "$ / do | E-Mail | Factory (: Benutzer, E-Mail: E-Mail) Ende Gegeben / ^ hat der Benutzer die E-Mail" ([^ "] *)" der Schnurrbart-Avatar $ / do | email | u = User.find_by_email (email) u.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' u.save end Dann / ^ sollte ich "([^"] *) "$ / do | content | page.should have_content (content) end Dann sollte / ^ das Profil "([^"] *) "$ / do | image | anzeigen n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). first ['src']. sollte = ~ pattern_for (image) end Gegeben / ^ I Ändern Sie die E-Mail mit "([^"] *) "für" ([^ "] *)" $ / do | new_email, old_email | u = User.find_by_email (old_email) Besuchen Sie edit_user_path (u) fill_in: email, mit: new_email click_button 'Speichern' end Gegeben / ^ Ich lade den Schnurrbart-Avatar für "([^"] *) "$ / do | email | u = User.find_by_email (email) Besuchen Sie edit_user_path (u) attach_file 'user [avatar_image]', Rails.root + 'spec / fixtures / mustache_avatar.jpg' click_button 'Save' end Gegeben / ^ der Benutzer "([^"] *) ) "hat den Schnurrbart - Avatar und ich entferne ihn $ / do | email | u = User.find_by_email (email) u.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' u.save visit edit_user_path (u) check "Avatarbild entfernen" click_button 'save' end Then / ^ der Benutzer " ([^ "] *)" sollte "([^"] *) "$ / do | email, image | haben u = User.find_by_email (email) Besuchen Sie user_path (u) n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). first ['src'] .should = ~ pattern_for (image) end def pattern_for (image_name) case image_name wenn 'der Platzhalter-Avatar' /placehold.it/, wenn 'der Schnurrbart-Avatar' / mustache_avatar / end end ist

S3-Unterstützung hinzufügen

Als letzten Schritt können wir S3-Unterstützung hinzufügen, um die Avatar-Dateien zu speichern. Lass uns wieder öffnen config / initializers / dragonfly.rb und aktualisieren Sie den Konfigurationsblock:

 Dragonfly :: App [: images] .configure do | c | c.datastore = Dragonfly :: DataStorage :: S3DataStore.new c.datastore.configure do | d | d.bucket_name = 'dragonfly_tutorial' d.access_key_id = 'some_access_key_id' d.secret_access_key = 'some_secret_access_key' end end, außer% (Entwicklungstestgurke) .include? Rails.env

Dies funktioniert sofort und wirkt sich nur auf die Produktion aus (oder auf eine andere Umgebung, die nicht in der Datei angegeben ist). In allen anderen Fällen verwendet Dragonfly standardmäßig den Dateisystemspeicher.


Fazit

Ich hoffe, Sie fanden dieses Tutorial interessant und haben ein paar interessante Leckerbissen von Informationen gefunden.

Ich empfehle Ihnen, auf der Dragonfly GitHub-Seite ausführliche Dokumentationen und andere Beispiele für Anwendungsfälle zu finden - auch außerhalb einer Rails-Anwendung.