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

Fat Modelの倒し方 / how to deal with fat model

Fat Modelの倒し方 / how to deal with fat model

銀座Rails#21 ( https://ginza-rails.connpass.com/event/173610/ ) の発表資料になります。

Ruby on Rails アプリケーションにおける Fat Model の解決方法を下記の3つに分けて紹介しています。
1. Rails Way
2. Sub-Rails Way
3. Non-Rails Way

本発表はBlogにも文書の形でまとめてありますのでそちらもあわせてご参照ください。
https://blog.toshimaru.net/how-to-deal-with-fat-model/

toshimaru

May 15, 2020
Tweet

More Decks by toshimaru

Other Decks in Technology

Transcript

  1. ࣗݾ঺հ toshimaru - GitHub: toshimaru - Twitter: toshimaru_e Rails Engineer

    @ MedPeer - We're Hiring ❗ OSS Activities: - Syntax Highlighted Go cat (toshimaru/nyan) - VSCode Color Theme (toshimaru/hybrid-next-plus) 2
  2. Fat Rails Stage Fat Stage Railsशख़౓ Fat Layer 1 ௿

    Fat View 2 த Fat Controller 3 ߴ Fat Model1 1 Buckblog: Skinny Controller, Fat Model 5
  3. ࿩͢͜ͱ • Fat Model ʹରॲ͢ΔͨΊͷΞϓϩʔνΛ੔ཧ • Fat Model ରॲʹ͋ͨΓͲͷΞϓϩʔνΛऔΔ΂͖͔ ࿩͞ͳ͍͜ͱ

    • ͦΕͧΕͷΞϓϩʔνͷ࣮૷ৄࡉɾ۩ମతͳ࣮૷ํ๏΍࣮૷ྫ • Fat Controller/Fat Viewͷରॲ๏ 7
  4. Rails Modelͷݶք఺ • 1ͭͷModel͕ෳ਺ͷҟͳΔϢʔεέʔεʹີ݁߹࣮ͯ͠૷͞Ε Δͱ͖ • → ͋Δ৚݅΍contextʹඥ෇͍ͨValidation/Callbackॲཧ • 1ͭͷϑΥʔϜͰෳ਺ͷαϒϦιʔε͕ߋ৽͞ΕΔͱ͖

    ʢϑΥʔϜͱModel͕1ର1Ͱඥ෇͔ͳ͍ͱ͖ʣ • → 1ͭͷModelΛى఺ͱͨ͠ෳ਺ModelΛލ͙τϥϯβΫ γϣϯॲཧ • Rails Model : DB Table = 1:1 ͷੈք؍ʹىҼ͢Δݶք 13
  5. 18

  6. Concerns • ⚠ ConcernͷެࣜΨΠυ͸ͳ͍ • DHH: Put chubby models on

    a diet with concerns • Modelͷ͍࣋ͬͯΔೳྗʢability = -able suffixʣʹண໨ͯ͠੾ Γग़͍ͯ͘͠ͷ͕Rails WayͬΆ͍ 21
  7. ͦͷଞࡉ͔ΊͷςΫχοΫ • Serialize Attribute • jsonܕΧϥϜ΁ͷϝλσʔλอଘʹศར • ⚠ ʰSQLΞϯνύλʔϯʱ5ষ EAV

    • Value Object (compose_of) • ෳ਺ΧϥϜΛValueΦϒδΣΫτͱͯ͠ల։͢Δͱ͖ʹศར 28
  8. ʮ1. Rails Wayʯ·ͱΊ • ! Rails Way͚ͩͰ͸Fat ModelΛ౗͢खஈͱͯ͠ख਺͕গͳ͘ ෺଍Γͳ͍ •

    ❌ Concerns, Validation ClassͳͲFat ModelΛDRYʹهड़͢ Δखஈʹ͸ͳΔ͕ɺߏ଄తʹμΠΤοτ͢Δखஈʹ͸ͳͬͯ ͳ͍ʢہॴతͳμΠΤοτࢭ·Γʣ • ❌ STI, PolymorphicͳͲ͸DBઃܭͱີ݁߹ͨ͠ιϦϡʔγϣ ϯͰɺ׬શͳίʔυϨϕϧͷղܾʹ͸ͳ͍ͬͯͳ͍ʢͦΕࣗ ମ͕ٕज़ෛ࠴ʹͳΓ͑Δߏ଄త໰୊ΛሃΜͰ͍Δʣ 30
  9. 32

  10. View Model • Modelʹ͓͚ΔViewؔ࿈ϩδοΫΛ View Model ͱͯ͠੾Γग़ ͢ • Development

    of Further PoEAA: Presentation Model • ModelΛDecoratorύλʔϯͬΆ֦͘ு͍ͯ͠ΔͷͰ Decorator ͱ΋ݺ͹ΕΔ8 • Fat View ͷରॲͱͯ͠΋ػೳ͢Δ఺͕˓ 8 ࢀߟ: ʰRubyʹΑΔσβΠϯύλʔϯʱୈ11ষ ΦϒδΣΫτΛվྑ͢ΔɿDecorator 35
  11. ಛఆͷ՝୊ͷղܾ • ࿦ཧ࡟আ • ! gem: discard, paranoia, acts_as_paranoid •

    ⚠ SQLΞϯνύλʔϯ ݬͷୈ26ষʮͱΓ͋͑ͣ࡟আϑϥ άʯ • ཁૉͷιʔτɾฒͼସ͑ • ! gem: acts_as_list, ranked-model 44
  12. ಛఆͷ՝୊ͷղܾ • State Machine • ! gem: aasm, stateful_enum •

    Tagging • ! gem: acts-as-taggable-on • HashΛActiveRecordͬΆ͘ૢ࡞ • ! gem: active_hash 45
  13. ʮͦΕRailsͰͰ͖ΔΑʯ10 • ! enumerize (Emumerized Attributes) • Rails 4.1: ActiveRecord

    enum • ! switch_point (Database R/W Split) • Rails 6: Multi-DB • ! activerecord-import (Bulk Import) • Rails 6: insert_all, upsert_all 10 Ruby/Railsެࣜͷఏڙ͢Δػೳ͸gemΑΓශऑͩͬͨΓ͢ΔͷͰ͔͋͠Βͣ 46
  14. ʮͦΕRailsͰͰ͖ΔΑʯ10 • ! carrierwave, shrine (File Uploader) • Rails 5.2:

    Active Storage • ! config (YAML Config Management) • Rails Custom configuration: • Rails::Application.config_for • config.x 10 Ruby/Railsެࣜͷఏڙ͢Δػೳ͸gemΑΓශऑͩͬͨΓ͢ΔͷͰ͔͋͠Βͣ 47
  15. ʮͦΕRailsͰͰ͖ΔΑʯ10 • ! friendly_id • ActiveRecord: to_param • ID/Passwordೝূ •

    ActiveModel: has_secure_password 10 Ruby/Railsެࣜͷఏڙ͢Δػೳ͸gemΑΓශऑͩͬͨΓ͢ΔͷͰ͔͋͠Βͣ 48
  16. ʮͦΕRubyͰͰ͖ΔΑʯ10 • ! pry • Ruby 2.4: binding.irb • Ruby

    2.7: REPL Syntax Highlighting 10 Ruby/Railsެࣜͷఏڙ͢Δػೳ͸gemΑΓශऑͩͬͨΓ͢ΔͷͰ͔͋͠Βͣ 49
  17. ʮ2. Sub-Rails Wayʯ·ͱΊ • ! gem Λ࢖͏͜ͱͰ Fat Model ରॲ๏ͷόϦΤʔγϣϯ͕޿

    ͕Δ • ✅ ಠ࣮ࣗ૷ͰModelΛଠΒͤͣɺ࢖͑Δgem͸ੵۃతʹར༻ ͠Α͏ • # ҰํɺgemΛ࢖Θͣͱ΋Railsඪ४ͰղܾͰ͖Δ͜ͱ΋ଟ ͍ͷͰݟۃΊ্ͨͰgemಋೖ͠Α͏ • $ બ୒ࢶ͸͞΄Ͳଟ͘ͳ͍͕ SaaS Λ࢖͏ͷ΋ Fat Model ର߅ खஈͷ̍ͭ 51
  18. 53

  19. Form Model • Form Model = include ActiveModel ͨ͠RubyΫϥεʢ͍ΘΏ Δ

    Form Objectʣ • ϑΥʔϜ:Form Model = 1:1 • ! gem • reform • dry-rbγϦʔζ3 3 چɾvirtus 55
  20. Form Model ඥͮ͘ςʔϒϧ਺ Ϣʔεέʔε 0 ໰͍߹ΘͤϑΥʔϜͳͲςʔϒϧ Λ࡞Δ·Ͱ΋ͳ͍ϑΥʔϜͰར༻ 1 - 4

    2Ҏ্ accepts_nested_attributes_for ͷ୅ΘΓͱͯ͠ෳࡶͳϑΥʔϜͷ ૊Έཱͯ࣌ʹར༻ 4 ςʔϒϧͱϑΥʔϜ͕1ର1Ͱඥͮ͘৔߹͸Rails WayͰղܾͤ͞·͠ΐ͏ 56
  21. PORO • PORO (Plain Old Ruby Object) • PoEAA: POJO

    (Plain Old Java Object) • ActiveRecord ͷػೳʹґଘ͠ͳ͍७ਮͳRuby࣮૷ • include ActiveModel • ७ਮͳRuby࣮૷ͳͷͰ͋Δҙຯ Ruby Way ͱݴ͑Δ • Model ͷิॿྠత໾ׂ 57
  22. Service Class • ⚠ αʔϏεͷఆٛ໰୊ → What is your "Service"?

    • PoEAA: Service Layer • DDD: Service Class • Onion Architecture: Application Service, Domain Service • Rails "Service" • ʮͲ͏͍͏จ຺ͷαʔϏε͔ʯΛ໌֬ʹ͠ͳ͍ͱService Class ͷఆٛɾ֓೦͕ϘϯϠϦ͢Δҹ৅ 59
  23. Service Class • αʔϏεΫϥεʹର͢Δݸਓతݟղ • Service Class ͷఆٛɾ࢖͍ํΛ໌֬ʹ্ͨ͠ͰνʔϜʹಋ ೖ͍ͯ͘͠ͷ͕٢ •

    ʮಛఆͷϢʔεέʔεͷղܾʯͱ͍͏ҙຯʹ͓͍ͯ͸ Interactor ͷ΄͏͕ʢগͳ͘ͱ΋Railsʹ͓͍ͯ͸ʣے͕ྑ͞ ͦ͏ • Լखʹ৽͍֓͠೦Λ࣋ͪࠐΉΑΓɺPORO ͱ͍͏֓೦Ͱࡶʹ ·ͱΊͨ΄͏͕޷Έ 60
  24. ʮ3. Non-Rails Wayʯ·ͱΊ • 4ͭͷ Non-Rails 1. Form Model 2.

    PORO 3. Service Class 4. 1 Table Multiple Models • ! ͏·͘ಋೖͰ͖Ε͹ Fat Model Λ౗͢ڧྗͳ෢ثͱͳΔ • " ਖ਼ղ͸ͳ͍ͱࢥ͏ͷͰνʔϜʹ͋ͬͨख๏Λબ୒͢Δͱྑ͍ 64
  25. શମͷ·ͱΊ Fat Model Λ౗ͨ͢Ίͷ3ͭͷΞϓϩʔν Λ঺հ͠·ͨ͠ɻ 1. Rails Way: Railsͷن໿ʹԊͬͨ։ൃ 2.

    Sub-Rails Way: Railsͷن໿ΛgemͰิڧɾ֦ு 3. Non-Rails Way: Railsͷن໿͔Β֎ΕΔಠ࣮ࣗ૷ 66
  26. ݁࿦ • ·ͣ͸ Rails Way + Sub-Rails Way ͰFat ModelΛμΠΤοτͰ

    ͖ͳ͍͔ߟ͑·͠ΐ͏ɻͦͷ্ͰඞཁʹԠͯ͡ద੾ͳ Non- Rails Way ΛऔΓೖΕ͍͖ͯ·͠ΐ͏ • Non-Rails Way ͸νʔϜຖʹ࠷దղ͕͋Δͱࢥ͏ͷͰɺνʔϜ Ͱ߹ҙͰ͖Δಠࣗ࿏ઢΛબ୒ɾಋೖ͢Ε͹Α͍ͷͰ͸ͳ͍Ͱ ͠ΐ͏͔ 67
  27. ࢀߟจݙ • Patterns of Enterprise Application Architecture by Martin Fowler

    • Clean Architecture by Robert Cecil Martin • Domain-Driven Design by Eric Evans • Growing Rails Applications in Practice by Henning Koch and Thomas Eisenbarth 69
  28. ࢀߟࢿྉ • Martin Fowler: Development of Further Patterns of Enterprise

    Application Architecture • Clean Coder Blog: The Clean Architecture • The Onion Architecture : part 1 | Programming with Palermo 70
  29. ࢀߟࢿྉ • RailsެࣜυΩϡϝϯτ • Active Record Associations — Ruby on

    Rails Guides • Active Model Basics — Ruby on Rails Guides • accepts_nested_attributes_for • ActiveRecord::Inheritance • ActiveSupport::Concern 71
  30. ࢀߟࢿྉ • தن໛Web։ൃͷͨΊͷMVC෼ׂͱϨΠϠΞʔΩςΫνϟ - Qiita • acceptsnestedattributes_forΛ࢖Θͣɺෳ਺ͷࢠϨίʔυΛอଘ ͢Δ | Money

    Forward Engineers' Blog • Concerns about Concerns - Speaker Deck • Model ͱը໘্ͷ form ͕1ର1ͰҰக͠ͳ͍৔߹ɺͲͷΑ͏ʹ ࣮૷͢Δͷ͕៉ྷͳͷ͔ʁ - clean-rails.org • Architecture: Interactors | Hanami Guides 72
  31. ࢀߟࢿྉ • RailsͰॏཁͳύλʔϯpart 1: Service Objectʢ຋༁ʣʛ TechRachoʢςοΫϥονϣʣʙΤϯδχΞͷʮʁʯΛʮʂʯ ʹʙʛBPSגࣜձࣾ • Decorator

    ͱ Presenter Λ࢖͍෼͚ͯɺ Rails Λ ViewModel Ͱ ͖ͬ͢Γͤ͞Α͏ - KitchHike Tech Blog • ͯΊ͑ΒͷRails͸ΦϒδΣΫτࢦ޲͡ΌͶ͑ʂ·ͣ͸Callback ΫϥεɺValidatorΫϥεΛ׆༻͠Ζʂ - Qiita 73
  32. ࢀߟࢿྉ • Why Service Objects are an Anti-Pattern — INTERSECT

    • Service Object͕ΞϯνύλʔϯͰ͋Δཧ༝ͱΑΓΑ͍୅ସ खஈʢ຋༁ʣʛTechRachoʢςοΫϥονϣʣʙΤϯδχΞ ͷʮʁʯΛʮʂʯʹʙʛBPSגࣜձࣾ • RailsͰෳ਺ϞσϧΛѻ͏ϑΥʔϜΛ͖ͬ͢Γॻ͘ʢFormΦϒ δΣΫτʣ - LiBz Tech Blog • ActiveRecordͷϞσϧ͕1ͭͩͱͭΒ͍ - Qiita 74