ApplicationModel のある風景 / Rails with ApplicationModel

9936ddaf95702abb005b5b7b0dd2bfd6?s=47 hshimoyama
December 08, 2018

ApplicationModel のある風景 / Rails with ApplicationModel

Railsdm 2018 Day4 Nouvelle Vague section B [15:50-16:10 ]

Rails アプリケーションの成長に伴い、単一の ActiveRecord モデルにロジックを記述するのに不都合が出てきます。今回、それらの問題を『緩やかに』解消するための ApplicationModel 層の導入・活用方法と、既存のアプローチとの簡単な比較をご紹介出来ればと思います。

9936ddaf95702abb005b5b7b0dd2bfd6?s=128

hshimoyama

December 08, 2018
Tweet

Transcript

  1. 8.
  2. 9.

    routes ΍ DB table Λߟ͑Δ • 1 Model • 1

    DB table • 1 View • 1 Controller • 1 REST resource
  3. 10.
  4. 16.

    R Customer:: M T C R’ C’ R’’ C’’ R’’’

    C’’’ R C R’ C’ R’’ C’’ R C R C Api:: Admin:: Etc::
  5. 18.

    R Customer:: M T C R’ C’ R’’ C’’ R’’’

    C’’’ R C R’ C’ R’’ C’’ R C R C Api:: Admin:: Etc::
  6. 21.

    R Customer:: M T C R’ C’ R’’ C’’ R’’’

    C’’’ R C R’ C’ R’’ C’’ R C R C Api:: Admin:: Etc::
  7. 22.

    ղܾͷΞϓϩʔν • ϞσϧΛ෼ׂ͢Δ • ϩδοΫΛॻ͘ͷʹઐ೦͢ΔͨΊͷϞσϧ • Rails ͷϨʔϧʹ͓͍ͯ༧ଌՄೳͳ໊শ REST resource

    Controller View Model DB Table /users UsersController users/* User users /admin/users Admin::
 UsersController admin/users/* User
 →Admin::User users
  8. 23.

    R Customer:: M T C R’ C’ R’’ C’’ R’’’

    C’’’ R C R’ C’ R’’ C’’ R C R C Api:: Admin:: Etc:: Customer::M Customer::M’ Customer::M’’ Customer::M’’’ Api::M Api::M’ Api::M’’ Admin::M Etc::M
  9. 29.

    • ◦ : Rails ͷػೳͰ࣮ݱग़དྷΔ • × : ActiveModel::Attribute ͕

    Internal API • × : ػೳతʹ෺଍Γͳ͍͕࣌͋Δ (ؔ࿈ (Nesting) ౳) • : ࣗલ࣮૷ → ݻ༗ͷෳࡶ͞ͷݩ ActiveModel ϕʔε class ApplicationModel include ActiveModel::Model include ActiveModel::Attributes end
  10. 30.

    • ◦ : ࡉ͔͘ΧελϚΠζग़དྷΔ • ◦ : ػೳతʹදݱग़དྷΔ෯͕޿͍ • ×

    : ֤छ gem ͷ஌͕ࣝඞཁ • × : ApplicationRecord ͱه๏͕ҟͳΔ • attribute/property(reform), validation/required(dry-rb) gem (dry-rb, reform) ϕʔε
  11. 31.

    • ௚ۙͷϓϩδΣΫτ͸ ActiveModel ϕʔεΛબ୒ • ؔ࿈ = Nesting ͕ແ͍ͷ͕ݫ͍͠ •

    ࣗલ࣮૷ͯ͠͠·ͬͨ෦෼͕ෛ࠴Խͯͦ͠͏ • ݱঢ়ͲΕ΋Ұ௕Ұ୹͋Γͦ͏ • dry-rb : ʰͲͷ gem Λ૊Έ߹Θ͔ͤͨʱ͕ෳࡶ • reform : Form ͱ͍͏໊෇͚ʹҾͬுΒΕΔ ͲΕΛબͿ΂͖͔ʁ
  12. 32.

    • ෼ׂͨ͠ Model ΛͲ͏ DRY ʹอ͔ͭʁ • όϦσʔγϣϯ • ڞ௨ػೳ

    • ApplicationModel Model ͷ attributes ͱ ApplicationRecord Model ͷ attributes ͷಉظ TIPS
  13. 33.

    • ڞ௨ͷόϦσʔγϣϯϧʔϧ • ApplicationRecord ͷ Model ʹॻ͘ • ಛఆ༻్ͷΑΓݫີͳόϦσʔγϣϯ •

    ApplicationModel ͷ Model ʹॻ͘ • ͦΕΒΛڞ௨Խ͢Δͱ͖͸ CustomValidator DRY : όϦσʔγϣϯ
  14. 35.

    • ApplicationModel Model ͱͯ͠ड͚औΓɺvalidation ʹ໰ ୊͕ແ͔ͬͨ࣌ɺActiveRecord Model ʹӬଓԽΛґཔ͢ Δ •

    Ͳͷ attribute ͕Ͳͷ attribute ʹରԠ͍ͯ͠Δͷ͔ʁ • ͲͷλΠϛϯάͰ஋Λίϐʔ͢Δͷ͔ʁ • ͦΕΒΛࣗಈԽ͢Δػೳ͸༻ҙ͞Ε͍ͯΔͷ͔ʁ Sync : attributes
  15. 36.

    • ActiveModel ϕʔεͷ ApplicationModel Ͱ͸ࣗલ࣮૷ Sync : attributes class Admin::User

    < ApplicationModel associate :user, User, default: -> { User.new } attribute :name, :string, for: :user validates_associated :user def save sync_attributes return false unless valid? user.save end end
  16. 37.

    Sync : attributes class Admin::UsersController < Admin::ApplicationController def new @admin_user

    = Admin::User.new end def create @admin_user = Admin::User.new(admin_user_create_params) if @admin_user.save redirect_to @admin_user else render :new end end def edit @admin_user = Admin::User.new(user: ::User.find(params[:id])) end def update @admin_user = Admin::User.new(admin_user_update_params) if @admin_user.save redirect_to @admin_user else render :edit end end # … end
  17. 38.

    • Ϩʔϧ͔Β͋·Γ֎Ε͍ͯͳ͍ (ͱࢥ͏) • σʔλ͸୯Ұͷ ApplicationRecord Model Λܦ༝͢Δ • ActiveRecord::Attributes

    ͰߦͬͯΔ cast ౳ͷॲཧ͕ ͋Ε͹ͦ͜ʹॻ͘ • ໊෇͚౳Ͱ͋·ΓࠔΒͳ͍ ApplicationModel ͷ
 Կ͕خ͍͠ͷ͔
  18. 40.

    Rails MVC Model ૚ͰରԠ • ApplicationRecord Model Λ෼ׂ͢Δ • ActiveRecordͷϞσϧ͕1ͭͩͱͭΒ͍(@hanachin_)


    https://qiita.com/hanachin_/items/ba1dd93905567d88145c • PORO (Pure Old Ruby Object) • RailsͷଠͬͨϞσϧΛμΠΤοτͤ͞Δํ๏ʹ͍ͭ ͯ (@willnet)
 https://tech.medpeer.co.jp/entry/2017/11/08/120000
  19. 41.
  20. 42.

    ApplicationRecord Model Λ෼ׂ͢Δ • ApplicationModel ͷར఺ • DB migration ࣌ʹ໘౗͕গͳ͍

    (ignore_columns) • ActiveRecord::AssociationTypeMismatch ղফύζϧ ʹͳΒͳ͍ • σʔλӬଓԽՕॴΛߜΕΔ
  21. 43.

    PORO • RailsͷଠͬͨϞσϧΛμΠΤοτͤ͞Δํ๏ʹ͍ͭͯ (@willnet)
 https://tech.medpeer.co.jp/entry/2017/11/08/120000 • ApplicationModel ͸ better PORO

    • Ϟσϧ૚ʹ͋ΔΫϥε͸ ApplicationRecord ΋͘͠͸ ApplicationModel Λܧঝͨ͠ΫϥεͷΈɺͱ͍͏੤໿ʹ ΑΓɺϞσϧ૚ʹظ଴͢Δڞ௨ͷৼΔ෣͍Λఆ͍ٛͯ͠Δ • PORO ͷํ͕ࣗ༝ͳར఺΋͋ΔͷͰ͓޷ΈͰ
  22. 44.

    Service / Form • Service / Form ͷྑ͍ͱ͜Ζ • ApplicationModel

    ͔Βߋʹ෼ׂ͞ΕɺϑΥʔΧε͢ Δ੹຿͕গͳ͍ • ੈؒతʹ͋Δఔ౓ೝ஌͞Ε͍ͯͯɺ֓೦͕ʢൺֱతʣ ఻ΘΓ΍͍͢ • (ҙ֎ͱ GraphQL mutation ͱ૬ੑ͕ྑ͍ͱࢥ͏)
  23. 45.

    Service / Form • Service / Form ͷͭΒ͍ͱ͜Ζ • ৽͍֓͠೦ͷಋೖ͕ඞཁͰϨʔϧ͔Βएׯ֎ΕΔ

    • ໊લ෇͚΍ݺͼग़͠खॱͷηΦϦʔཱ͓֬ͯ͠Βͣɺ ਪଌ͕೉͍͠ • ApplicationRecord Model ෼ׂͷ߲Ͱ৮Εͨ ApplicationModel ͷ໘౗͞Λ Service / Form ΋౿ऻ ͍ͯ͠Δ
  24. 46.

    Rails MVC Λ֦ு • ઃܭख๏͸ड͚ೖΕΒΕ͍ͯΔ͕ɺRails Ͱͷ࣮ݱํ๏͕ ཱ֬͞Ε͍ͯͳ͍΋ͷ • Clean Architecture

    • Layered Architecture • Rails Ͱͷ࣮ݱํ๏ཱ͕֬͞Ε͍ͯΔ΋ͷ • Trailblazer
  25. 47.

    Rails MVC Λ֦ு • ݸਓతʹ͸ಋೖʹ৻ॏ • ͜ΕΒΛಋೖ͢ΔΤϯδχΞ͸શମΛʰઃܭ͢Δʱ෦෼ʹ ڧΈΛ࣋ͬͨਓ͕ଟ͘ɺඞͣ͠΋ӡ༻Λಘҙͱ͍ͯ͠ͳ͍ • Ҿ͖ܧ͙ϝϯόʔ͕ಋೖ͞Εͨઃܭख๏ʹशख़͍ͯ͠ͳ͍

    Մೳੑͷ΄͏͕ߴ͍ • େن໛։ൃͰϝϦοτΛे෼ʹڗडग़དྷΔ͔ɺઃܭख๏ʹ͍ͭͯ ਂ͘शख़ͨ͠ϝϯόʔΛἧ͑ଓ͚ΒΕΔͷͰ͋Ε͹… • ͱʹ͔͘ɺϨʔϧ͔Βେ͖͘ҳ୤͢ΔͷͰಋೖʹʰ֮ޛʱ͕ඞཁ
  26. 48.

    ApplicationModel 
 ΛબͿ΂͖͔ʁ • ٻΊΒΕΔ੹຿෼ׂͷཻ౓ͰબΜͰྑͦ͞͏ • 1 ApplicationRecord • N

    ApplicationRecord • N ApplicationModel + 1 ApplicationRecord • N Forms + N’ Services + 1 ApplicationRecord • Trailblazer, Clean Architecture, Layered Architecture