File Upload 2017

File Upload 2017

RejectKaigi 2017で発表した資料です。ActiveStorageの機能を紹介する過程で、ファイルアップロードを実装するのに必要な要件と選択肢について解説しています。

6ac7c50770603b53964d44db373e8e48?s=128

Shinichi Maeshima

August 19, 2017
Tweet

Transcript

  1. File Upload 2017 @willnet

  2. RejectKaigi • ;ͭ͏ͷRailsΤϯδχΞͩͱMRI͍ͬͨ͡Γ͠ͳ͍ͷͰͳ͔ͳ ͔CFPͩͤͳ͍ • ͔͠͠Α͘Α͘ߟ͑ΔͱREST΍APIɺΞϓϦέʔγϣϯαʔό ͳͲͷςʔϚ΋࠾୒͞ΕͯΔ • ॲཧܥҎ֎ͷ࿩Ͱ΋௨Δͱ͸ࢥ͏Μ͚ͩͲԿ͔͔͋ͬͨͳ…

  3. RubyKaigiͱࢲ • File UploadͳΒ஌ݟ͋Δ͍͚͠ΔͷͰ͸ʁ • ؾ͍ͮͨͷ͕ఏग़ظݶޙ !

  4. RejectKaigiͰ࿩ͦ͏

  5. ࣗݾ঺հ • લౡਅҰ aka @willnet or @netwillnet • ginza.rb ͔Βདྷ·ͨ͠

    • ϑϦʔϥϯεRailsٕज़ސ໰ • https://github.com/willnet • https://twitter.com/netwillnet • http://blog.willnet.in
  6. ؔ࿈ॻ੶ WEB+DB PRESS Vol.95 ͰϑΝΠϧΞοϓϩʔυͷ࿩Λॻ͖·ͨ͠

  7. File Upload

  8. File Uploadͬͯ೉͍͠ΜͰ͢Α…! • ϑΝΠϧΛͲ͜Ͱม׵͢Δ͔ • Ͳ͜ʹอଘ͢Δ͔ • όϦσʔγϣϯΛͲ͏͢Δ͔ • ηΩϡϦςΟΛͲ͏୲อ͢Δ͔

    • շదʹϑΝΠϧΛΞοϓϩʔυ͢Δʹ͸Ͳ͏͢Δ͔ • Ξοϓϩʔυͨ͠ϑΝΠϧͷΞΫηεݖݶ
  9. ϑΝΠϧΞοϓϩʔυػೳ • ଟ͘ͷߟྀ͢΂͖ཁૉ͕͋Δ • εΫϥονͰ࣮૷͢Δͷ͸͍ͨ΁Μ

  10. gemΛ࢖͓͏ !

  11. Ruby੡ͷओͳϑΝΠϧΞοϓϩʔυϥΠϒϥϦ • paperclip • carrierwave • dragonfly • refile •

    shrine • attache • active_storage(new!)
  12. ͲͷϥΠϒϥϦΛ࢖͏ͱ͍͍ΜͰ͢ ͔ʙʁ ! ✋

  13. ཁ ݅ ࣍ ୈ

  14. ͱ͸͍ͬͯ΋ԿΛͲ͏બΜͩΒ͍͍ͷ͔… ϑΝΠϧΞοϓϩʔυͷ • ߟྀ͢΂͖ཁૉ • ͦͷબ୒ࢶ ͱϥΠϒϥϦͷػೳΛ೺Ѳ͢Δͱબ΂ΔͷͰ͸

  15. શ෦࿩͢ͷ͸ແཧ

  16. ͦ͜Ͱࠓ೔͸ (Railsͷ࿩ͰڪॖͰ͕͢)ΈΜͳؾʹͳΔActive Storageͷػೳ঺հ Λ௨ͯ͡ϑΝΠϧΞοϓϩʔυશൠʹ͍ͭͯ࿩͠·͢

  17. ͦ΋ͦ΋Active Storageͱ͸ʁ • Rails 5.2ͰೖΔ༧ఆͷػೳ • mountable engineͱͯ͠࡞ΒΕͨ • ͭ·ΓಠࣗͷϧʔςΟϯάɺίϯτϩʔϥɺϞσϧ͕͋Δ

  18. Active Storageͷಛ௃ • ϙϦϞʔϑΟοΫؔ࿈ • ΞΫηε࣌ม׵ • ੍࣌ؒݶ෇͖ͷURLΛ؆୯ʹѻ͑Δ • μΠϨΫτΞοϓϩʔυରԠ

    • ϛϥʔػೳ
  19. Active Storage Λ࢖͏લͷ४උ AttachmentͱBlob༻ͷςʔϒϧΛ࡞Δ ./bin/rails active_storage:install ./bin/rails db:migrate

  20. ϙϦϞʔϑΟοΫؔ࿈ • ϑΝΠϧ؅ཧ༻ͷϞσϧ͕༻ҙ͞Ε͍ͯΔ • Attachment (தؒςʔϒϧ) • Blob (ϑΝΠϧͷϝλ৘ใ) •

    UserͳͲͷϞσϧʹϑΝΠϧ༻ͷΧϥϜΛ௥Ճ͠ͳ͍ܗࣜ • ͢΂ͯͷϑΝΠϧΛˢͷ2ͭͰ؅ཧ͢Δ
  21. ϝϦοτ • εΩʔϚͷมߋʹॊೈ

  22. ϝϦοτͷྫ • 1Ϣʔβ1ΞόλʔͰӡ༻͍͕ͯͨ͠ɺ1Ϣʔβෳ਺Ξόλʔʹ࢓ ༷มߋ͕͋ͬͨ • ଞϥΠϒϥϦͩͱςʔϒϧͷ௥Ճ͕ඞཁʹͳΔ • Active StorageͩͱεΩʔϚ৘ใͷมߋ͕ඞཁͳ͍

  23. σϝϦοτ ͢΂ͯͷछྨͷϑΝΠϧ৘ใ͕Blobʹ֨ೲ͞ΕΔ • Ξόλʔ • ը૾Ξοϓϩʔυ • ϑΝΠϧڞ༗

  24. Ϟσϧ class User < ApplicationRecord has_one_attached :avatar end class Gallery

    < ApplicationRecord has_many_attached :photos end
  25. Ϗϡʔ(ϑΥʔϜ) <%= form.file_field :avatar %>

  26. ίϯτϩʔϥ def create @user = User.new(user_params) if @user.save @user.avatar.attach( io:

    params[:user][:avatar], filename: 'avatar.jpeg' ) redirect_to @user, notice: 'User was successfully created.' else render :new end end
  27. ը૾ͷදࣔ <%= image_tag user.avatar.variant(resize: "100x100") %>

  28. Active Storage͸ΞΫηε࣌ม׵ܗࣜ • dragonfly, refile, attacheͳͲ͕࠾༻͍ͯ͠Δܗࣜ • ม׵ͷܗࣜΛؚΊͨURLͰΞΫηε • ม׵ܗࣜΛ૿΍͢ͱ͖ͷࣄલ४උ͕ෆཁͰָ

    • ΞϓϦέʔγϣϯαʔόʹෛՙ͕͔͔Δ৔߹͕͋Δ
  29. ෛՙ͕͔͔Δྫ 1. ը૾ΛҰ౓ʹͨ͘͞ΜΞοϓϩʔυ 2. ը૾ҰཡϖʔδʹભҠ 3. ͨ͘͞Μͷը૾ͷม׵͕ಉ࣌ʹ࣮ߦ͞ΕΔ

  30. ෛՙΛ෼ࢄ͠Α͏ͱ͢ΔϥΠϒϥϦ΋͋Δ • attache͕࠾༻͍ͯ͠Δ΍Γํ • (·ͩ࢓ࣄͰ͔ͭ͑Δײ͡Ͱ͸ͳ͍Ͱ͢) • ΞϓϦέʔγϣϯͱ͸ಠཱͨ͠ը૾༻ͷαʔόΛཱͯͯɺAPIͰ ΍ΓͱΓ͢Δ • CloudinaryΈ͍ͨͳPaasΛࣗલͰӡ༻͢ΔΠϝʔδ

    • microservice
  31. Active StorageͳΒͰ͸ͷಛ௃ • ॳճΞΫηε࣌ʹม׵ͨ͠΋ͷΛΫϥ΢υʹΞοϓϩʔυ • Ϋϥ΢υ΁ͷURL΁ϦμΠϨΫτ • σϑΥϧτ5෼ͷظݶ෇͖URL • ύʔϚωϯτͳURL͸ΞϓϦέʔγϣϯαʔόͷURL

  32. ϑΝΠϧ΁ͷΞΫηεڐՄ • Active Storage͸ظݶ෇͖ͷURLΛ࠾༻ • ΊͣΒ͍͠ • େ఍͸ྨਪͷ೉͍͠URLͰOKͱ͢Δ͜ͱ͕ଟ͍ • ݫີʹݖݶΛνΣοΫ͢ΔͱΞϓϦέʔγϣϯαʔόʹෛՙ

    ͕͔͔Δ • Active Storage ↑ͷ໰୊Λ͏·͘ղܾ͍ͯ͠Δ
  33. ଞͷม׵ܗࣜ • Ξοϓϩʔυ࣌ʹม׵ • όοΫάϥ΢ϯυͰม׵

  34. Ξοϓϩʔυ࣌ʹม׵ • paperclip, carrierwaveͳͲ͕࠾༻ • ࣮૷తʹ͸Ұ൪ૉ௚Ͱཧղ͠΍͍͢ • ϑΝΠϧม׵͢Δ࣌ؒɺϢʔβΛ଴ͨͤΔ͜ͱʹͳΔ • ΞϓϦέʔγϣϯαʔόʹෛՙ͕͔͔Δ

    • ม׵͢Δछྨ͕ଟ͍ • ϑΝΠϧΞοϓϩʔυ͕ूத͢Δ࣌ؒଳ
  35. όοΫάϥϯυͰม׵ • shrine͕࠾༻ • ΞοϓϩʔυͷλΠϛϯάͰΩϡʔʹม׵λεΫΛ٧ΊΔ • όοΫάϥ΢ϯυϫʔΧʔ͕ॱ൪ʹม׵͍ͯ͘͠ͷͰෛՙͷ໰ ୊ΛܰݮͰ͖Δ • ม׵͕ऴΘΔલʹը૾͕ඞཁʹͳΔέʔεͰࠔΔ

  36. μΠϨΫτΞοϓϩʔυ • ΞϓϦέʔγϣϯαʔόΛܦ༝ͤͣΫϥ΢υʹ௚઀Ξοϓϩʔ υ • ΞϓϦέʔγϣϯαʔόͷෛՙ௿ݮ • ͍͔ͭ͘ͷϥΠϒϥϦͰαϙʔτ͍ͯ͠Δ • ϑΥʔϜͷsubmit࣌ʹΞοϓϩʔυ

  37. μΠϨΫτΞοϓϩʔυ application.js //= require activestorage _form.html.erb <%= form.filefield :avatar, direct_upload:

    true %>
  38. Ξοϓϩʔυઌͷઃఆ(Ұ෦) config/storage.yml test: service: Disk root: <%= Rails.root.join("tmp/storage") %> local:

    service: Disk root: <%= Rails.root.join("storage") %> # amazon: # service: S3 # access_key_id: <%= Rails.application.secrets.dig(:aws, :access_key_id) %> # secret_access_key: <%= Rails.application.secrets.dig(:aws, :secret_access_key) %> # region: us-east-1 # bucket: your_own_bucket
  39. config/environments/development.rbͳͲ config.active_storage.service = :local

  40. ϛϥʔͷઃఆ ಉ࣌ʹෳ਺ͷΫϥ΢υετϨʔδʹΞοϓϩʔυͯ͠όοΫΞο ϓͰ͖Δ config/storage.yml mirror: service: Mirror primary: amazon mirrors:

    [ google, microsoft ]
  41. Ұ௨Γಛ௃࿩ͨ͠

  42. Կ͔଍Γͯͳ͍΋ͷ͋ΔΑ͏ͳ!

  43. Active Storegeʹݱঢ়଍Γ͍ͯͳ͍Α͏ʹΈ͑ Δ΋ͷ • όϦσʔγϣϯ • cache

  44. όϦσʔγϣϯ େ఍ͷϥΠϒϥϦʹ͸όϦσʔγϣϯͷαϙʔτ͕͋Δ͕ɺݱঢ় ͷActive Storegeʹ͸ͳ͔ͥଘࡏ͠ͳ͍

  45. όϦσʔγϣϯྫ • ϑΝΠϧܗࣜͷ֬ೝ • ֦ுࢠ • Content Type

  46. όϦσʔγϣϯྫ • ϑΝΠϧͷେ͖͞ • ༰ྔ • ը૾ͷॎ෯ԣ෯: Biggest image in

    the smallest space
  47. όϦσʔγϣϯ • PRνϟϯε? • ͔͠͠Ϟσϧ͕ڞ༗ͳͷͰ࣮૷ͮ͠Β͍ • ྫ: Ξόλʔ͸5MB͚ͩͲͦΕҎ֎ͷࣸਅ͸10MB·ͰOK

  48. cache • ଞͷϥΠϒϥϦͰ͸΄΅αϙʔτ͞Ε͍ͯΔ • όϦσʔγϣϯΤϥʔ࣌ͷϑΝΠϧஔ͖৔

  49. cacheͷྫ 1. ը૾ͱίϝϯτΛϑΥʔϜ͔Βૹ৴ 2. ίϝϯτ͕όϦσʔγϣϯΤϥʔ 3. ը૾͸cacheྖҬʹอଘ͍ͯ͠ΔͷͰίϝϯτ͚ͩमਖ਼ͯ͠࠶ ૹ৴ 4. ը૾͸cacheྖҬ͔Βຊ൪ྖҬʹҠಈ͢Δ

  50. cache αϯϓϧίʔυ͕͜͏ͳͷͰɺຖճΞοϓϩʔυ͠Ζͱ͍͏ׂΓ ੾Γʹݟ͑Δ class MessagesController < ApplicationController # ུ def

    create message = Message.create! params.require(:message).permit(:title, :content) message.images.attach(params[:message][:images]) redirect_to message end # ུ end
  51. ·ͱΊ Active Storageͷػೳ঺հΛ௨ͯ͡ɺϑΝΠϧΞοϓϩʔυͷ • ߟྀ͢΂͖ཁૉ • ͦͷબ୒ࢶ ͷҰ෦Λ঺հ͠·ͨ͠

  52. ·ͱΊ • ϑΝΠϧΞοϓϩʔυͷ೉͠͞ɺ఻ΘΓ·͔ͨ͠ʁ • ສೳͳϥΠϒϥϦ͸ͳ͍ͷͰɺཁ݅ݟͯ࢖͍෼͚·͠ΐ͏

  53. Happy File Uploading !"⬆!