Slide 1

Slide 1 text

ApplicationModel ͷ͋Δ෩ܠ Hiroyasu Shimoyama Web engineer at giftee inc. Twitter@_h_s_

Slide 2

Slide 2 text

Overview • ApplicationModel ಋೖͷഎܠͱϞνϕʔγϣϯ • ApplicationModel ૚ͷ঺հ • طଘͷΞϓϩʔνͱͷൺֱ

Slide 3

Slide 3 text

Rails ͷϓϩμΫτ։ൃ • ॳΊ͸γϯϓϧ • ঃʑʹෳࡶʹ • ෳࡶ͞ͱͲ͏޲͖߹͍͔ͬͯ͘ʁ

Slide 4

Slide 4 text

ෳࡶ͞ • ආ͚ΒΕΔෳࡶ͞ͱɺආ͚ΒΕͳ͍ෳࡶ͞ • ݻ༗ͷෳࡶ͞ͱɺҰൠతͳෳࡶ͞ • ੔ཧ͞Εͨෳࡶ͞ͱɺແடংͳෳࡶ͞ • ༧ଌՄೳͳෳࡶ͞ͱɺ༧ଌࠔ೉ͳෳࡶ͞

Slide 5

Slide 5 text

Rails ͷϨʔϧ • Rails ͷෳࡶ͞Λཧղ͢Δ͜ͱͰ • ආ͚ΒΕΔෳࡶ͞Λආ͚Δ • Ұൠతͳෳࡶ͞Λղܾ͢Δ • ෳࡶ͞Λ੔ཧͯ͠ίϯτϩʔϧ͢Δ • ༧ଌՄೳʹ͢Δ

Slide 6

Slide 6 text

Rails MVC

Slide 7

Slide 7 text

γϯϓϧͳੈք • 1 Model • 1 View • 1 Controller

Slide 8

Slide 8 text

C M V

Slide 9

Slide 9 text

routes ΍ DB table Λߟ͑Δ • 1 Model • 1 DB table • 1 View • 1 Controller • 1 REST resource

Slide 10

Slide 10 text

C M V T R

Slide 11

Slide 11 text

গ͠ෳࡶͳੈք • ಉҰͷσʔλΛҟͳΔϦιʔεͱͯ͠ݟͤΔ • ҟͳΔ REST resource

Slide 12

Slide 12 text

C M V T R C’ V’ R’

Slide 13

Slide 13 text

΋͏গ͠ෳࡶͳੈք • ϦιʔεΛҟͳΔίϯςΩετͰݟΔ • ؅ཧը໘ / API / etc. • namespace

Slide 14

Slide 14 text

R C V R’ C’ V’ R C V Customer:: M T Admin::

Slide 15

Slide 15 text

΋ͬͱෳࡶͳੈք • ݱ࣮͸ΑΓݫ͘͠ɺෳࡶʹͳΔҰํ • ݟͤํ͕૿͑Δ : Ϧιʔεͷ૿Ճ • ༻్͕૿͑Δ : ίϯςΩετͷ૿Ճ

Slide 16

Slide 16 text

R Customer:: M T C R’ C’ R’’ C’’ R’’’ C’’’ R C R’ C’ R’’ C’’ R C R C Api:: Admin:: Etc::

Slide 17

Slide 17 text

ߋʹෳࡶͳੈք • ͦΕͧΕ͕୲͏੹຿΋૿Ճ͍ͯ͘͠ • ௨஌ / ඇಉظॲཧ / ֎෦APIґଘ / ঢ়ଶ؅ཧ / etc. • Model ͷෳࡶ͞ ++

Slide 18

Slide 18 text

R Customer:: M T C R’ C’ R’’ C’’ R’’’ C’’’ R C R’ C’ R’’ C’’ R C R C Api:: Admin:: Etc::

Slide 19

Slide 19 text

୯ҰͷϞσϧʹ ෳࡶ͕͞ूத

Slide 20

Slide 20 text

୯ҰϞσϧͷ໰୊ • ѻ͍͍ͨσʔλ → 1 Table (ͱͦͷؔ࿈) → 1 Model • σʔλΛѻ͏શͯͷෳࡶ͞ → 1 Model

Slide 21

Slide 21 text

R Customer:: M T C R’ C’ R’’ C’’ R’’’ C’’’ R C R’ C’ R’’ C’’ R C R C Api:: Admin:: Etc::

Slide 22

Slide 22 text

ղܾͷΞϓϩʔν • ϞσϧΛ෼ׂ͢Δ • ϩδοΫΛॻ͘ͷʹઐ೦͢ΔͨΊͷϞσϧ • Rails ͷϨʔϧʹ͓͍ͯ༧ଌՄೳͳ໊শ REST resource Controller View Model DB Table /users UsersController users/* User users /admin/users Admin::
 UsersController admin/users/* User
 →Admin::User users

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

Ͳ͏ϨʔϧʹࡌͤΔ͔ • ʰςʔϒϧʹඥ෇͔ͳ͍Ϟσϧ૚ʱΛۃྗϨʔϧ͔Β֎Ε ͳ͍Α͏ʹఆٛ͠ɺͦΕΛཧղ͢Δ͜ͱͰ • ආ͚ΒΕΔෳࡶ͞Λආ͚Δ • Ұൠతͳෳࡶ͞Λղܾ͢Δ • ෳࡶ͞Λ੔ཧͯ͠ίϯτϩʔϧ͢Δ • ༧ଌՄೳʹ͢Δ

Slide 25

Slide 25 text

ApplicationModel

Slide 26

Slide 26 text

• Controller ͕ Model ʹظ଴͢Δڞ௨ͷৼΔ෣͍Λදݱ͢ Δ • ςʔϒϧʹඥ෇͍ͨϞσϧ → ApplicationRecord • ςʔϒϧʹඥ෇͔ͳ͍Ϟσϧ → ApplicationModel ApplicationModel

Slide 27

Slide 27 text

• ApplicationRecord Model Λѻ͏Α͏ʹѻ͍͍ͨ • Attributes • όϦσʔγϣϯ • ؔ࿈ͷදݱ • etc. ApplicationModel ʹ
 ظ଴͢Δػೳͷྫ

Slide 28

Slide 28 text

• ActiveModel ϕʔε • gem (virtus, dry-rb, reform) ϕʔε ApplicationModel ͷ࣮૷

Slide 29

Slide 29 text

• ○ : Rails ͷػೳͰ࣮ݱग़དྷΔ • × : ActiveModel::Attribute ͕ Internal API • × : ػೳతʹ෺଍Γͳ͍͕࣌͋Δ (ؔ࿈ (Nesting) ౳) • : ࣗલ࣮૷ → ݻ༗ͷෳࡶ͞ͷݩ ActiveModel ϕʔε class ApplicationModel include ActiveModel::Model include ActiveModel::Attributes end

Slide 30

Slide 30 text

• ○ : ࡉ͔͘ΧελϚΠζग़དྷΔ • ○ : ػೳతʹදݱग़དྷΔ෯͕޿͍ • × : ֤छ gem ͷ஌͕ࣝඞཁ • × : ApplicationRecord ͱه๏͕ҟͳΔ • attribute/property(reform), validation/required(dry-rb) gem (dry-rb, reform) ϕʔε

Slide 31

Slide 31 text

• ௚ۙͷϓϩδΣΫτ͸ ActiveModel ϕʔεΛબ୒ • ؔ࿈ = Nesting ͕ແ͍ͷ͕ݫ͍͠ • ࣗલ࣮૷ͯ͠͠·ͬͨ෦෼͕ෛ࠴Խͯͦ͠͏ • ݱঢ়ͲΕ΋Ұ௕Ұ୹͋Γͦ͏ • dry-rb : ʰͲͷ gem Λ૊Έ߹Θ͔ͤͨʱ͕ෳࡶ • reform : Form ͱ͍͏໊෇͚ʹҾͬுΒΕΔ ͲΕΛબͿ΂͖͔ʁ

Slide 32

Slide 32 text

• ෼ׂͨ͠ Model ΛͲ͏ DRY ʹอ͔ͭʁ • όϦσʔγϣϯ • ڞ௨ػೳ • ApplicationModel Model ͷ attributes ͱ ApplicationRecord Model ͷ attributes ͷಉظ TIPS

Slide 33

Slide 33 text

• ڞ௨ͷόϦσʔγϣϯϧʔϧ • ApplicationRecord ͷ Model ʹॻ͘ • ಛఆ༻్ͷΑΓݫີͳόϦσʔγϣϯ • ApplicationModel ͷ Model ʹॻ͘ • ͦΕΒΛڞ௨Խ͢Δͱ͖͸ CustomValidator DRY : όϦσʔγϣϯ

Slide 34

Slide 34 text

• ҎԼͷͲͪΒ͔ • Concerns • ApplicationModel Model • ΦϓγϣφϧͳৼΔ෣͍ͷ࣌͸લऀɺ୯Ұػೳͱͯ͠੒ཱ ͢Δ৔߹͸ޙऀΛબ୒͢Δ͜ͱ͕ଟ͍ DRY : ڞ௨ػೳ

Slide 35

Slide 35 text

• ApplicationModel Model ͱͯ͠ड͚औΓɺvalidation ʹ໰ ୊͕ແ͔ͬͨ࣌ɺActiveRecord Model ʹӬଓԽΛґཔ͢ Δ • Ͳͷ attribute ͕Ͳͷ attribute ʹରԠ͍ͯ͠Δͷ͔ʁ • ͲͷλΠϛϯάͰ஋Λίϐʔ͢Δͷ͔ʁ • ͦΕΒΛࣗಈԽ͢Δػೳ͸༻ҙ͞Ε͍ͯΔͷ͔ʁ Sync : attributes

Slide 36

Slide 36 text

• 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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

• Ϩʔϧ͔Β͋·Γ֎Ε͍ͯͳ͍ (ͱࢥ͏) • σʔλ͸୯Ұͷ ApplicationRecord Model Λܦ༝͢Δ • ActiveRecord::Attributes ͰߦͬͯΔ cast ౳ͷॲཧ͕ ͋Ε͹ͦ͜ʹॻ͘ • ໊෇͚౳Ͱ͋·ΓࠔΒͳ͍ ApplicationModel ͷ
 Կ͕خ͍͠ͷ͔

Slide 39

Slide 39 text

طଘͷΞϓϩʔνͱͷൺֱ • ApplicationRecord Model Λ෼ׂ͢Δ • PORO (Plane Old Ruby Object) • Service / Form • Rails MVC Λ֦ு͢Δ

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

ApplicationRecord Model Λ෼ׂ͢Δ • ActiveRecordͷϞσϧ͕1ͭͩͱͭΒ͍(@hanachin_)
 https://qiita.com/hanachin_/items/ba1dd93905567d88145c • ϒϩάهࣄͰݕ౼͞Ε͍ͯΔ௨Γɺඇৗʹ্ख͘work ͢ Δ • ApplicationRecord Model ෼ׂͰ΋ྑ͍ͱࢥ͏ • ʰActiveRecordҎ֎ͷ૚ͭ͘Δͱҙ֎ͱ໘౗ʱͰ΋ ݴٴ͞Ε͍ͯΔ௨Γɺ͔֬ʹ໘౗

Slide 42

Slide 42 text

ApplicationRecord Model Λ෼ׂ͢Δ • ApplicationModel ͷར఺ • DB migration ࣌ʹ໘౗͕গͳ͍ (ignore_columns) • ActiveRecord::AssociationTypeMismatch ղফύζϧ ʹͳΒͳ͍ • σʔλӬଓԽՕॴΛߜΕΔ

Slide 43

Slide 43 text

PORO • RailsͷଠͬͨϞσϧΛμΠΤοτͤ͞Δํ๏ʹ͍ͭͯ (@willnet)
 https://tech.medpeer.co.jp/entry/2017/11/08/120000 • ApplicationModel ͸ better PORO • Ϟσϧ૚ʹ͋ΔΫϥε͸ ApplicationRecord ΋͘͠͸ ApplicationModel Λܧঝͨ͠ΫϥεͷΈɺͱ͍͏੤໿ʹ ΑΓɺϞσϧ૚ʹظ଴͢Δڞ௨ͷৼΔ෣͍Λఆ͍ٛͯ͠Δ • PORO ͷํ͕ࣗ༝ͳར఺΋͋ΔͷͰ͓޷ΈͰ

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Service / Form • Service / Form ͷͭΒ͍ͱ͜Ζ • ৽͍֓͠೦ͷಋೖ͕ඞཁͰϨʔϧ͔Βएׯ֎ΕΔ • ໊લ෇͚΍ݺͼग़͠खॱͷηΦϦʔཱ͓֬ͯ͠Βͣɺ ਪଌ͕೉͍͠ • ApplicationRecord Model ෼ׂͷ߲Ͱ৮Εͨ ApplicationModel ͷ໘౗͞Λ Service / Form ΋౿ऻ ͍ͯ͠Δ

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

Rails MVC Λ֦ு • ݸਓతʹ͸ಋೖʹ৻ॏ • ͜ΕΒΛಋೖ͢ΔΤϯδχΞ͸શମΛʰઃܭ͢Δʱ෦෼ʹ ڧΈΛ࣋ͬͨਓ͕ଟ͘ɺඞͣ͠΋ӡ༻Λಘҙͱ͍ͯ͠ͳ͍ • Ҿ͖ܧ͙ϝϯόʔ͕ಋೖ͞Εͨઃܭख๏ʹशख़͍ͯ͠ͳ͍ Մೳੑͷ΄͏͕ߴ͍ • େن໛։ൃͰϝϦοτΛे෼ʹڗडग़དྷΔ͔ɺઃܭख๏ʹ͍ͭͯ ਂ͘शख़ͨ͠ϝϯόʔΛἧ͑ଓ͚ΒΕΔͷͰ͋Ε͹… • ͱʹ͔͘ɺϨʔϧ͔Βେ͖͘ҳ୤͢ΔͷͰಋೖʹʰ֮ޛʱ͕ඞཁ

Slide 48

Slide 48 text

ApplicationModel 
 ΛબͿ΂͖͔ʁ • ٻΊΒΕΔ੹຿෼ׂͷཻ౓ͰબΜͰྑͦ͞͏ • 1 ApplicationRecord • N ApplicationRecord • N ApplicationModel + 1 ApplicationRecord • N Forms + N’ Services + 1 ApplicationRecord • Trailblazer, Clean Architecture, Layered Architecture

Slide 49

Slide 49 text

·ͱΊ • ApplicationModel Λಋೖ͢Δͱɺscaffold Ͱ࡞ͬͨϞσϧ ͷΑ͏ʹϩδοΫهड़૚Λಋೖग़དྷ·͢ • طଘͷΞϓϩʔνʹൺ΂ͯར఺ܽ఺͸͋Δ͚ΕͲɺϨʔϧ ʹԊͬͨ։ൃ͸͠΍͍͢ͱࢥ͍·͢ • બ୒ࢶͷҰͭͱͯ͠ࢹ໺ʹ͓͍ͯ௖͚ͨΒ޾͍Ͱ͢

Slide 50

Slide 50 text

“Arigato!”