Upgrade to Pro — share decks privately, control downloads, hide ads and more …

File Upload 2017

File Upload 2017

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

Shinichi Maeshima

August 19, 2017
Tweet

More Decks by Shinichi Maeshima

Other Decks in Programming

Transcript

  1. File Upload 2017
    @willnet

    View Slide

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

    View Slide

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

    View Slide

  4. RejectKaigiͰ࿩ͦ͏

    View Slide

  5. ࣗݾ঺հ
    • લౡਅҰ aka @willnet or @netwillnet
    • ginza.rb ͔Βདྷ·ͨ͠
    • ϑϦʔϥϯεRailsٕज़ސ໰
    • https://github.com/willnet
    • https://twitter.com/netwillnet
    • http://blog.willnet.in

    View Slide

  6. ؔ࿈ॻ੶
    WEB+DB PRESS Vol.95 ͰϑΝΠϧΞοϓϩʔυͷ࿩Λॻ͖·ͨ͠

    View Slide

  7. File Upload

    View Slide

  8. File Uploadͬͯ೉͍͠ΜͰ͢Α…!
    • ϑΝΠϧΛͲ͜Ͱม׵͢Δ͔
    • Ͳ͜ʹอଘ͢Δ͔
    • όϦσʔγϣϯΛͲ͏͢Δ͔
    • ηΩϡϦςΟΛͲ͏୲อ͢Δ͔
    • շదʹϑΝΠϧΛΞοϓϩʔυ͢Δʹ͸Ͳ͏͢Δ͔
    • Ξοϓϩʔυͨ͠ϑΝΠϧͷΞΫηεݖݶ

    View Slide

  9. ϑΝΠϧΞοϓϩʔυػೳ
    • ଟ͘ͷߟྀ͢΂͖ཁૉ͕͋Δ
    • εΫϥονͰ࣮૷͢Δͷ͸͍ͨ΁Μ

    View Slide

  10. gemΛ࢖͓͏ !

    View Slide

  11. Ruby੡ͷओͳϑΝΠϧΞοϓϩʔυϥΠϒϥϦ
    • paperclip
    • carrierwave
    • dragonfly
    • refile
    • shrine
    • attache
    • active_storage(new!)

    View Slide

  12. ͲͷϥΠϒϥϦΛ࢖͏ͱ͍͍ΜͰ͢
    ͔ʙʁ ! ✋

    View Slide


  13. ݅


    View Slide

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

    View Slide

  15. શ෦࿩͢ͷ͸ແཧ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. ϙϦϞʔϑΟοΫؔ࿈
    • ϑΝΠϧ؅ཧ༻ͷϞσϧ͕༻ҙ͞Ε͍ͯΔ
    • Attachment (தؒςʔϒϧ)
    • Blob (ϑΝΠϧͷϝλ৘ใ)
    • UserͳͲͷϞσϧʹϑΝΠϧ༻ͷΧϥϜΛ௥Ճ͠ͳ͍ܗࣜ
    • ͢΂ͯͷϑΝΠϧΛˢͷ2ͭͰ؅ཧ͢Δ

    View Slide

  21. ϝϦοτ
    • εΩʔϚͷมߋʹॊೈ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  25. Ϗϡʔ(ϑΥʔϜ)

    View Slide

  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

    View Slide

  27. ը૾ͷදࣔ

    View Slide

  28. Active Storage͸ΞΫηε࣌ม׵ܗࣜ
    • dragonfly, refile, attacheͳͲ͕࠾༻͍ͯ͠Δܗࣜ
    • ม׵ͷܗࣜΛؚΊͨURLͰΞΫηε
    • ม׵ܗࣜΛ૿΍͢ͱ͖ͷࣄલ४උ͕ෆཁͰָ
    • ΞϓϦέʔγϣϯαʔόʹෛՙ͕͔͔Δ৔߹͕͋Δ

    View Slide

  29. ෛՙ͕͔͔Δྫ
    1. ը૾ΛҰ౓ʹͨ͘͞ΜΞοϓϩʔυ
    2. ը૾ҰཡϖʔδʹભҠ
    3. ͨ͘͞Μͷը૾ͷม׵͕ಉ࣌ʹ࣮ߦ͞ΕΔ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. ଞͷม׵ܗࣜ
    • Ξοϓϩʔυ࣌ʹม׵
    • όοΫάϥ΢ϯυͰม׵

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  37. μΠϨΫτΞοϓϩʔυ
    application.js
    //= require activestorage
    _form.html.erb

    View Slide

  38. Ξοϓϩʔυઌͷઃఆ(Ұ෦)
    config/storage.yml
    test:
    service: Disk
    root:
    local:
    service: Disk
    root:
    # amazon:
    # service: S3
    # access_key_id:
    # secret_access_key:
    # region: us-east-1
    # bucket: your_own_bucket

    View Slide

  39. config/environments/development.rbͳͲ
    config.active_storage.service = :local

    View Slide

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

    View Slide

  41. Ұ௨Γಛ௃࿩ͨ͠

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  51. ·ͱΊ
    Active Storageͷػೳ঺հΛ௨ͯ͡ɺϑΝΠϧΞοϓϩʔυͷ
    • ߟྀ͢΂͖ཁૉ
    • ͦͷબ୒ࢶ
    ͷҰ෦Λ঺հ͠·ͨ͠

    View Slide

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

    View Slide

  53. Happy File Uploading !"⬆!

    View Slide