Hoe bestanden te uploaden met gemak met behulp van DragonFly

Bestandsuploads zijn over het algemeen een lastig gebied in webontwikkeling. In deze tutorial leren we Dragonfly te gebruiken, een krachtige Ruby-edelsteen die het gemakkelijk en efficiënt maakt om elke vorm van uploadfunctionaliteit aan een Rails-project toe te voegen.


Wat we gaan bouwen

In onze voorbeeldtoepassing wordt een lijst met gebruikers weergegeven en voor elk daarvan kunnen we een avatar uploaden en opslaan. Bovendien stelt Dragonfly ons in staat om:

  • Dynamisch afbeeldingen manipuleren zonder extra exemplaren op te slaan
  • Maak gebruik van HTTP-caching om onze toepassingsbelasting te optimaliseren

In deze les volgen we een BDD-benadering (Behavior Driven Development) met behulp van Cucumber en RSpec.


voorwaarden

U moet Imagemagick geïnstalleerd hebben: u kunt deze pagina raadplegen om de binaries te installeren. Omdat ik gebaseerd ben op een Mac-platform, gebruik Homebrew, ik kan gewoon typen zet imagemagick in voor installatie.

Je zult ook een basis Rails-applicatie moeten klonen die we als uitgangspunt zullen gebruiken.


Opstelling

We beginnen met het klonen van de startrepository en het instellen van onze afhankelijkheden:

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

Deze applicatie vereist tenminste Ruby 1.9.2 om te draaien, maar ik moedig je aan om 1.9.3 te gebruiken. De Rails-versie is 3.2.1. Het project omvat geen .rvmrc of a .rbenv het dossier.

Vervolgens voeren we:

bundel installeren bundel exec hark db: setup db: test: prepare db: seed

Dit zorgt voor de edelsteenafhankelijkheden en database-instellingen (we zullen sqlite gebruiken, dus maak je geen zorgen over databaseconfiguratie).

Om te testen of alles werkt zoals verwacht, kunnen we het volgende uitvoeren:

bundel exec rspec bundel exec komkommer

Je zou moeten merken dat alle tests zijn geslaagd. Laten we de output van komkommer bekijken:

 Functie: gebruikersprofiel beheren Als gebruiker Om mijn gegevens te beheren, wil ik toegang krijgen tot mijn gebruikersprofielpagina Achtergrond: Gegeven een gebruiker bestaat met e-mailadres "[email protected]" Scenario: mijn profiel bekijken Gezien ik op de startpagina aanwezig ben Ik volg 'Profiel' voor '[email protected]'. Dan zou ik op de profielpagina moeten staan ​​voor '[email protected]'. Scenario: mijn profiel bewerken Aangezien ik op de profielpagina voor '[email protected]' ben wanneer Ik volg "Bewerken" en ik verander mijn e-mailadres met "[email protected]" En ik klik op "Opslaan". Dan zou ik op de profielpagina moeten staan ​​voor "[email protected]" En ik zou "User updated" 2 scenario's moeten zien (2 geslaagd) 11 stappen (11 geslaagd) 0m0.710s

Zoals je ziet, beschrijven deze functies een typische gebruikersworkflow: we openen een gebruikerspagina uit een lijst, drukken op "Bewerken" om de gebruikersgegevens te bewerken, de e-mail te wijzigen en op te slaan.

Probeer nu de app uit te voeren:

rails s

Als je opent http :: // localhost: 3000 in de browser vindt u een lijst met gebruikers (we hebben de database vooraf gevuld met 40 willekeurige records dankzij de Faker-edelsteen).

Voor nu hebben alle gebruikers een kleine avatar van 16x16px en een grote avatar voor placeholder op hun profielpagina. Als u de gebruiker bewerkt, kunt u de details wijzigen (voornaam, achternaam en wachtwoord), maar als u een avatar probeert te uploaden, wordt deze niet opgeslagen.

Voel je vrij om door de codebase te bladeren: de applicatie gebruikt Simple Form om formulierweergaven en Twitter Bootstrap voor CSS en lay-out te genereren, omdat ze perfect integreren en veel helpen bij het versnellen van het prototypingproces.


Functies voor Avatar Upload

We beginnen met het toevoegen van een nieuw scenario aan features / managing_profile.feature:

... Scenario: een avatar toevoegen Gegeven ik ben op de profielpagina voor "[email protected]" Wanneer ik "Bewerken" volg Ik upload de snoravatar En ik klik op "Opslaan" Dan zou ik op de profielpagina moeten staan ​​voor "e-mail" @ example.com "En in het profiel moet" de snoravatar "worden weergegeven

Deze functie spreekt voor zich, maar er zijn een paar extra stappen nodig om aan toe te voegen features / step_definitions / user_steps.rb:

... Wanneer / ^ upload ik de avatar avatar $ / do attach_file 'gebruiker [avatar_image]', Rails.root + 'spec / fixtures / mustache_avatar.jpg' end Dan / ^ het profiel zou moeten tonen "([^"] *) " $ / do | image | pattern = case image wanneer 'the mustache avatar' / mustache_avatar / end n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']") .eerste ['src']. zou = ~ patroon eindigen

Deze stap gaat ervan uit dat je een afbeelding hebt, genaamd mustache_avatar.jpg binnen spec / fixtures. Zoals je zou kunnen raden, is dit slechts een voorbeeld; het kan alles zijn wat je wilt.

De eerste stap gebruikt Capybara om de user [avatar_image] bestandsveld en upload het bestand. Merk op dat we ervan uitgaan dat we een a zullen hebben avatar_image attribuut op de Gebruiker model-.

De tweede stap gebruikt Nokogiri (een krachtige HTML / XML-parsbibliotheek) en XPath om de inhoud van de resulterende profielpagina te analyseren en naar de eerste te zoeken img tag met a thumbnail klasse en test dat de src kenmerk bevat mustache_avatar.

Als je rent komkommer nu zal dit scenario een fout activeren, omdat er geen bestand is met de naam die we hebben opgegeven. Het is nu tijd om ons te concentreren op de Gebruiker model-.


Dragonfly-ondersteuning toevoegen aan het gebruikersmodel

Voordat Dragonfly wordt geïntegreerd met de Gebruiker model, laten we een paar specs toevoegen user_spec.rb.

We kunnen een nieuw blok toevoegen direct na de attributen context:

 context "avatar attributen" do it should response_to (: avatar_image) it should allow_mass_assignment_of (: avatar_image) einde

We testen dat de gebruiker een heeft avatar_image attribuut en omdat we dit kenmerk via een formulier willen bijwerken, moet het toegankelijk zijn (tweede specificatie).

Nu kunnen we Dragonfly installeren: hierdoor krijgen we deze specificaties om groen te worden.

Laten we de volgende regels toevoegen aan Gemfile:

 gem 'rack-cache', vereisen: 'rack / cache' gem 'dragonfly', '~> 0.9.10'

Vervolgens kunnen we rennen bundel installeren. Rack-cache is nodig tijdens de ontwikkeling, omdat dit de eenvoudigste optie is om HTTP-caching te hebben. Het kan ook in de productie worden gebruikt, zelfs als robuustere oplossingen (zoals Varnish of Squid) beter zouden zijn.

We moeten ook de Dragonfly-initializer toevoegen. Laten we het maken config / initialiseerders / dragonfly.rb bestand en voeg het volgende toe:

 vereisen 'dragonfly' app = Dragonfly [: afbeeldingen] app.configure_with (: imagemagick) app.configure_with (: rails) app.define_macro (ActiveRecord :: Base,: image_accessor)

Dit is de vanille-Dragonfly-configuratie: het installeert een Dragonfly-applicatie en configureert het met de benodigde module. Er wordt ook een nieuwe macro aan toegevoegd ActiveRecord die we kunnen gebruiken om onze Gebruiker model-.

We moeten updaten config / application.rb, en voeg een nieuwe richtlijn toe aan de configuratie (vlak voor de config.generators blok):

 config.middleware.insert 0, 'Rack :: Cache', verbose: true, metastore: URI.encode ("file: # Rails.root / tmp / dragonfly / cache / meta"), entitystore: URI.encode ("bestand: # Rails.root / tmp / dragonfly / cache / body") tenzij Rails.env.production? config.middleware.insert_after 'Rack :: Cache', 'Dragonfly :: Middleware',: images

Zonder in te gaan op veel details, zijn we aan het opzetten Rack :: Cache (behalve voor productie, waar dit standaard is ingeschakeld) en Dragonfly instellen om het te gebruiken.

We slaan onze afbeeldingen op schijf op, maar we hebben een manier nodig om de koppeling met een gebruiker bij te houden. De eenvoudigste optie is om twee kolommen toe te voegen aan de gebruikerstabel met een migratie:

rails g migratie add_avatar_to_users avatar_image_uid: string avatar_image_name: stringbundel exec rake db: migrate db: test: voorbereiden

Nogmaals, dit is regelrecht uit de documentatie van Dragonfly: we moeten een avatar_image_uid kolom om het avatar-bestand uniek te identificeren en een avatar_image_name om de originele bestandsnaam op te slaan (de laatste kolom is niet strikt nodig, maar het maakt het genereren van afbeeldings-urls mogelijk die eindigen met de originele bestandsnaam).

Eindelijk kunnen we het Gebruiker model:

 klasse Gebruiker < ActiveRecord::Base image_accessor :avatar_image attr_accessible :email, :first_name, :last_name, :avatar_image… 

De image_accessor methode wordt beschikbaar gemaakt door de Dragonfly-initialisator, en het vereist slechts een attribuutnaam. We maken hetzelfde kenmerk ook toegankelijk in de regel hieronder.

hardlopen rspec nu moeten alle specificaties groen zijn.


Uploaden en weergeven van de avatar


Om de upload-functie te testen, kunnen we een context toevoegen users_controller_spec.rb in de PUT update blok:

 context "avatar afbeelding" do let! (: image_file) fixture_file_upload ('/ mustache_avatar.jpg', 'image / jpg') context "upload een avatar" doe voordat je het invoert: update, id: user.id, user: avatar_image: image_file einde het "zou de image record effectief op de gebruiker moeten opslaan" do user.reload user.avatar_image_name.should = ~ / mustache_avatar / end end end

We zullen hetzelfde armatuur opnieuw gebruiken en een mock maken om mee te uploaden fixture_file_upload.

Omdat deze functionaliteit gebruikmaakt van Dragonfly, hoeven we geen code te schrijven om deze te laten passeren.

We moeten nu onze standpunten bijwerken om de avatar te tonen. Laten we beginnen vanaf de gebruikersshow-pagina en openen app / views / users / show.html.erb en werk het bij met de volgende inhoud:

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

<%= @user.name %>

<%= @user.email %>


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

Vervolgens kunnen we updaten 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 gave 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 %>

We kunnen de gebruikersavatar tonen met een eenvoudige aanroep naar @ user.avatar_image.url. Hierdoor wordt een URL geretourneerd naar een niet-gewijzigde versie van de avatar die door de gebruiker is geüpload.

Als je rent komkommer nu zie je de groene functie. Probeer het ook eens in de browser uit!

We zijn impliciet afhankelijk van CSS om het formaat van de afbeelding te wijzigen als deze te groot is voor de bijbehorende container. Het is een wankele aanpak: onze gebruiker kan niet-vierkante avatars uploaden, of een heel kleine afbeelding. Bovendien serveren we altijd dezelfde afbeelding, zonder al te veel aandacht voor de paginagrootte of bandbreedte.

We moeten op twee verschillende gebieden werken: enkele validatieregels toevoegen aan de avatar-upload en beeldgrootte en -ratio specificeren met Dragonfly.


Validaties uploaden

We beginnen met het openen van de user_spec.rb bestand en een nieuw spec-blok toevoegen:

 context "avatar attributen" do% w (avatar_image retained_avatar_image remove_avatar_image) .each do | attr | it should response_to (attr.to_sym) end% w (avatar_image retained_avatar_image remove_avatar_image) .each do | attr | it should allow_mass_assignment_of (attr.to_sym) einde "moet de bestandsgrootte van de avatar valideren" do user.avatar_image = Rails.root + 'spec / fixtures / huge_size_avatar.jpg' user.should_not be_valid # size is> 100 KB einde het "zou het formaat van de avatar moeten valideren" do user.avatar_image = Rails.root + 'spec / fixtures / dummy.txt' user.should_not be_valid end end

We testen op aanwezigheid en staan ​​"massatoewijzing" toe voor extra kenmerken die we zullen gebruiken om het gebruikersformulier te verbeteren (: retained_avatar_image en : remove_avatar_image).

Daarnaast testen we ook dat ons gebruikersmodel geen grote uploads accepteert (meer dan 200 kB) en bestanden die geen afbeeldingen zijn. Voor beide gevallen moeten we twee fixture-bestanden toevoegen (een afbeelding met de opgegeven naam en met een grootte van meer dan 200 KB en een tekstbestand met inhoud).

Zoals gebruikelijk, zal het gebruik van deze specificaties ons niet groen maken. Laten we het gebruikersmodel bijwerken om die validatieregels toe te voegen:

... attr_accessible: email,: first_name,: last_name,: avatar_image,: retained_avatar_image,: remove_avatar_image ... validates_size_of: avatar_image, maximum: 100.kilobytes validates_property: format, of:: avatar_image, in: [: jpeg,: png,: gif, : jpg] validates_property: mime_type, of:: avatar_image, in: ['image / jpg', 'image / jpeg', 'image / png', 'image / gif'], case_sensitive: false

Deze regels zijn redelijk effectief: houd er rekening mee dat we niet alleen het formaat controleren, maar ook het mime-type controleren op een betere veiligheid. Omdat we een afbeelding zijn, staan ​​we jpg-, png- en gif-bestanden toe.

Onze specificaties moeten nu worden doorgegeven, dus het is tijd om de weergaven bij te werken om de beeldbelasting te optimaliseren.


Dynamische beeldverwerking

Dragonfly gebruikt standaard ImageMagick om afbeeldingen dynamisch te verwerken wanneer daarom wordt gevraagd. Aangenomen dat we een gebruiker Bijvoorbeeld in een van onze standpunten, kunnen we dan:

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

Deze methoden zullen een verwerkte versie van deze afbeelding creëren met een unieke hash en dankzij onze cachinglaag wordt ImageMagick slechts één keer per afbeelding aangeroepen. Hierna wordt de afbeelding direct vanuit de cache geserveerd.

Je kunt veel ingebouwde methoden gebruiken of gewoon je eigen bouwen, de documentatie van Dragonfly heeft genoeg voorbeelden.

Laten we onze gebruiker opnieuw bezoeken Bewerk pagina en update de weergavecode:

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

We doen hetzelfde voor de gebruiker laten zien pagina:

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

We dwingen de afbeeldingsgrootte tot 400 x 400 pixels. De # parameter geeft ook de opdracht aan ImageMagick om de afbeelding bij te snijden met behoud van een centrale zwaartekracht. Je kunt zien dat we dezelfde code op twee plaatsen hebben, dus laten we dit refactoren in een gedeeltelijke naam views / users / _avatar_image.html.erb

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

Dan kunnen we de inhoud van de .thumbnail container met een eenvoudige oproep naar:

 
<%= render 'avatar_image' %>

We kunnen het nog beter doen door het argument van te verplaatsen duim van de gedeeltelijke. Laten we updaten _avatar_image.html.erb:

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

We kunnen nu onze gedeeltelijke twee argumenten noemen: een voor het gewenste aspect en een voor de gebruiker:

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

We kunnen het fragment hierboven gebruiken Bewerk en laten zien weergaven, terwijl we het op de volgende manier naar binnen kunnen noemen views / users / _user_table.html.erb, waar we de kleine miniaturen tonen.

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

In beide gevallen voeren we ook een Regex uit op het aspect om een ​​tekenreeks uit te pakken die compatibel is met de service placehold.it (dat wil zeggen niet-alfanumerieke tekens verwijderen).


De Avatar verwijderen


Dragonfly maakt twee extra attributen die we in een vorm kunnen gebruiken:

  • retained_avatar_image: dit slaat de geüploade afbeelding op tussen herlaadbeurten. Als validaties voor een ander formulierveld (bijvoorbeeld e-mail) mislukken en de pagina opnieuw wordt geladen, is de geüploade afbeelding nog steeds beschikbaar zonder dat deze opnieuw hoeft te worden geladen. We zullen het rechtstreeks in de vorm gebruiken.
  • remove_avatar_image: wanneer het waar is, wordt de huidige avatarafbeelding zowel uit de gebruikersrecord als uit de schijf verwijderd.

We kunnen de avatarverwijdering testen door een extra spec toe te voegen aan users_controller_spec.rb, in de avatar afbeelding blok:

... context "een avatar verwijderen" do before user.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' user.save end it "zou de avatar van de gebruiker moeten verwijderen" do put: update, id: user. id, user: remove_avatar_image: "1" user.reload user.avatar_image_name.should be_nil end end ... 

Nogmaals, Dragonfly zal deze specificatie automatisch laten passeren omdat we al de remove_avatar_image kenmerk beschikbaar voor de gebruikersinstantie.

Laten we dan nog een functie toevoegen aan managing_profile.feature:

 Scenario: een avatar verwijderen Aangezien de gebruiker met het e-mailadres '[email protected]' de avatar voor de snor heeft en ik op de profielpagina '[email protected]' zit, wanneer ik 'Bewerken' volg en ik 'Avatarafbeelding verwijderen' aanvink En ik klik op 'Opslaan'. Dan zou ik op de profielpagina moeten staan ​​voor '[email protected]'. In het profiel moet 'de avatar voor plaatsaanduidingen' worden weergegeven

Zoals gewoonlijk, moeten we enkele stappen toevoegen aan user_steps.rb en update er een om een ​​Regex toe te voegen voor de placeholder-avatar:

 Gegeven / ^ de gebruiker met e-mail "([^"] *) "heeft de snor avatar $ / do | email | u = User.find_by_email (e-mail) u.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg 'u.save end When / ^ I check "([^"] *) "$ / do | checkbox | check checkbox end Then / ^ het profiel zou moeten tonen "([^"] *) "$ / do | image | pattern = case image when 'the placeholder avatar' /placehold.it/ when 'the sneak avatar' / mustache_avatar / end n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). first ['src']. should = ~ patroon einde

We moeten ook twee extra velden toevoegen aan de Bewerk het formulier:

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

Hierdoor krijgt onze functie een goed resultaat.


Functies refactoren

Om een ​​grote en te gedetailleerde functie te voorkomen, kunnen we dezelfde functionaliteit testen in een verzoekspecificatie.

Laten we een nieuw bestand maken met de naam spec / verzoeken / user_flow_spec.rb en voeg deze inhoud eraan toe:

 vereisen 'spec_helper' beschrijven "Gebruikersstroom" wel laten! (: gebruiker) Fabriek (: gebruiker, e-mail: "[email protected]") beschrijven "het profiel bekijken" doe het "zou het profiel voor de gebruiker moeten weergeven" ga naar '/' page.find ('tr', tekst: user.email) .click_link ("Profile") current_path = URI.parse (current_url) .path current_path.should == user_path (gebruiker) end end omschrijven "updaten" profielgegevens "do it" moeten de wijzigingen opslaan "do visit" / 'page.find (' tr ', text: user.email) .click_link ("Profile") click_link' Bewerken 'fill_in: email, met: "new_email @ example.com "click_button" Bewaar 'current_path.should == user_path (user) page.should have_content "User updated" end end omschrijven "managing the avatar" do it "zou de geüploade avatar moeten opslaan" do user.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' user.save bezoek user_path (gebruiker) click_link 'Edit' attach_file 'user [avatar_image]', Rails.root + 'spec / fixtures / mustache_avatar.jpg' click_button 'Opslaan' current_path.should == user_path (gebruiker) page.should have_con tent "Gebruiker bijgewerkt" n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). first ['src']. should = ~ / mustache_avatar / end het "zou de avatar moeten verwijderen indien gevraagd" do user.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' user.save bezoek user_path (gebruiker) click_link 'Bewerken' vinkje "Avatar afbeelding verwijderen" click_button 'Bewaar' current_path .should == user_path (user) page.should have_content "User updated" n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). eerst [' src ']. should = ~ /placehold.it/ end end end

De specificatie omvat alle stappen die we hebben gebruikt om onze hoofdfunctie te definiëren. Het test de opmaak en de flow grondig, zodat we ervoor kunnen zorgen dat alles naar behoren werkt op een gedetailleerd niveau.

Nu kunnen we de managing_profile.feature:

 Functie: gebruikersprofiel beheren Als gebruiker Om mijn gegevens te beheren, wil ik toegang krijgen tot mijn gebruikersprofielpagina Achtergrond: Gegeven een gebruiker bestaat met e-mailadres "[email protected]" Scenario: mijn profiel bewerken Gegeven verander ik de e-mail met "new_mail" @ example.com "voor" [email protected] "Dan zou ik" Gebruiker bijgewerkt "moeten zien Scenario: een avatar toevoegen Gaf ik de avatar voor de snor voor" [email protected] ". Vervolgens zou in het profiel" de avatar van de snor "moeten staan Scenario: een avatar verwijderen Gegeven de gebruiker "[email protected]" heeft de avatar van de snor en ik verwijder deze. Vervolgens moet de gebruiker "[email protected]" de "plaatsaanduidende avatar" hebben

bijgewerkt user_steps.rb:

 Gegeven / ^ een gebruiker bestaat met e-mail "([^"] *) "$ / do | email | Factory (: user, email: email) end Given / ^ de gebruiker met e-mail" ([^ "] *)" heeft de snor avatar $ / do | email | u = User.find_by_email (e-mail) u.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' u.save end Dan / ^ Ik zou moeten zien "([^"] *) "$ / do | content | page.should have_content (content) end Then / ^ het profiel zou moeten tonen "([^"] *) "$ / do | image | n = Nokogiri :: HTML (page.body) n.xpath (".// img [@ class = 'thumbnail']"). first ['src']. should = ~ pattern_for (image) end Given / ^ I verander de e-mail met "([^"] *) "voor" ([^ "] *)" $ / do | new_email, old_email | u = User.find_by_email (old_email) bezoek edit_user_path (u) fill_in: email, met: new_email click_button 'Save' end Given / ^ Ik upload de snoravatar voor "([^"] *) "$ / do | email | u = User.find_by_email (email) bezoek edit_user_path (u) attach_file 'gebruiker [avatar_image]', Rails.root + 'spec / fixtures / mustache_avatar.jpg' click_button 'Opslaan' end Given / ^ de gebruiker "([^"] * ) "heeft de avatar van de snor en ik verwijder deze $ / do | email | u = User.find_by_email (e-mail) u.avatar_image = Rails.root + 'spec / fixtures / mustache_avatar.jpg' u.save bezoek edit_user_path (u) vink "Avatar afbeelding verwijderen" aan click_button 'Opslaan' en dan / ^ de gebruiker " ([^ "] *)" should have "([^"] *) "$ / do | email, image | u = User.find_by_email (e-mail) bezoek 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 when 'the placeholder avatar' /placehold.it/ when 'the snor avatar' / mustache_avatar / end end

S3-ondersteuning toevoegen

Als laatste stap kunnen we eenvoudig S3-ondersteuning toevoegen om de avatarbestanden op te slaan. Laten we heropenen config / initialiseerders / dragonfly.rb en werk het configuratieblok bij:

 Dragonfly :: App [: afbeeldingen] .configuratie 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 tenzij% (ontwikkelingstest komkommer). Rails.env

Dit werkt out of the box en heeft alleen invloed op de productie (of een andere omgeving die niet in het bestand is gespecificeerd). Dragonfly zal standaard de systeemopslag voor alle andere gevallen opslaan.


Conclusie

Ik hoop dat je deze tutorial interessant hebt gevonden en een paar interessante weetjes hebt weten op te halen.

Ik moedig je aan om naar de Dragonfly GitHub-pagina te gaan voor uitgebreide documentatie en andere voorbeelden van use-cases - zelfs buiten een Rails-applicatie.