Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
フォームオブジェクトとの向き合い方/Grow Form Objects up
Search
MOROHASHI Kyosuke
July 14, 2018
Programming
1
2k
フォームオブジェクトとの向き合い方/Grow Form Objects up
Talk at Rails DM Day3 extreme
See also
https://railsdm.herokuapp.com/issues/78
MOROHASHI Kyosuke
July 14, 2018
Tweet
Share
More Decks by MOROHASHI Kyosuke
See All by MOROHASHI Kyosuke
Identifying User Idenity
moro
10
18k
Simplicity on Rails -- RDB, REST and Ruby
moro
15
18k
ちょうどよい Rails E2E テスト/enough-good-rails-e2e-test
moro
5
2.5k
フレームワークを作らない方法/How NOT to build frameworks
moro
4
1.2k
全体がいい感じになるために、私たちRailsをホームにするWeb技術者ができること/let-our-whole-system-grow
moro
2
1.9k
チームによるいきいきとしたソフトウェア開発/an-alive-team-grows-software
moro
3
3.4k
Web-E2E-Testing-from-Ruby
moro
5
560
Joyful user foundation restructuring with Ruby
moro
9
19k
cookpad-17day-tech-internship-2017-git
moro
0
9.5k
Other Decks in Programming
See All in Programming
Quand Symfony, ApiPlatform, OpenAI et LangChain s'allient pour exploiter vos PDF : de la théorie à la production…
ahmedbhs123
0
150
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
2
640
Modern Angular with Signals and Signal Store:New Rules for Your Architecture @enterJS Advanced Angular Day 2025
manfredsteyer
PRO
0
200
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
430
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
230
データの民主化を支える、透明性のあるデータ利活用への挑戦 2025-06-25 Database Engineering Meetup#7
y_ken
0
340
AIエージェントはこう育てる - GitHub Copilot Agentとチームの共進化サイクル
koboriakira
0
510
Claude Code + Container Use と Cursor で作る ローカル並列開発環境のススメ / ccc local dev
kaelaela
0
210
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
260
関数型まつりレポート for JuliaTokai #22
antimon2
0
160
チームのテスト力を総合的に鍛えて品質、スピード、レジリエンスを共立させる/Testing approach that improves quality, speed, and resilience
goyoki
4
600
Team topologies and the microservice architecture: a synergistic relationship
cer
PRO
0
1.2k
Featured
See All Featured
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.5k
Music & Morning Musume
bryan
46
6.6k
Unsuck your backbone
ammeep
671
58k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
KATA
mclloyd
30
14k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Side Projects
sachag
455
42k
Site-Speed That Sticks
csswizardry
10
680
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.4k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Building Applications with DynamoDB
mza
95
6.5k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
810
Transcript
ϑΥʔϜΦϒδΣΫτͱͷ ͖߹͍ํ 2018-07-11 Rails Developers Meetup 2018 Day 3 Extreme
ॾڮګհ @moro
‣ (ࣸਅ) Title
Kyosuke MOROHASHI moro moro
None
גࣜձࣾΤεɾΤϜɾΤε ۀɺ౦ূҰ෦্ɻ ߴྸࣾձΛհޢɾҩྍɾΩϟϦΞɾϔϧεέΞɾ γχΞϥΠϑͱଊ͑ɺߴྸࣾձʹదͨ͠ใαʔ ϏεΛଟ։ൃɾӡӦ
https://www.wantedly.com/companies/sms
͖ΐ͏ͷ
‣ “RailsͷΩϨΠͳઃܭ"࠷ॳ͔Βͯ͢ઃܭ͢Δͷ Ή͔͍ͣ͠ͷͰ෮ͯ͠࡞ΔͱΑͦ͞͏ɻ ‣ ʰॅΈͳ͕Β૿ங͍ͯ͘͠ײ͡ʱ@m_seki https://speakerdeck.com/m_seki/re-iterative-development-iteration-4?slide=57 ‣ Railsʹ͓͍ͯɺͦͷͱ͔͔ͬΓͱͯ͠ϑΥʔϜʹ ண͢Δͷѱ͘ͳͦ͞͏ɻ ͖ΐ͏ͷ
എܠ
‣ DBͷςʔϒϧʹ΄΅Ұகͨ͠ߏͷσʔλ͕POST͞Εͯ ͖ͯɺͦΕΛARͰγϯϓϧʹӬଓԽ͢Δɻ ‣ ͳ͔ͳ͔ͦ͏ߦ͔ͳ͍͜ͱଟ͍ΑͶɻ ૉͳRails͕ఆ͍ͯ͠Δ͜ͱ
‣ Ϣʔβʔ͕ʹ͢Δใ୯Ґ(≒ϑΥʔϜͷߏ)ͱɺਖ਼نԽ ͞ΕͨσʔλߏҟͳΔɻ ‣ DBʹӬଓԽ͢Δ͚ͩͰࡁ·ͳ͍͜ͱ͕͋Δɻ ‣ ϝʔϧΛૹΔɺϩάΛऔΔɺඇಉظδϣϒΛΩοΫ͢Δɺ Πϕϯτͱͯ͠Publish͢ΔɺɺɺͳͲͳͲ “ͦ͏ߦ͔ͳ͍͜ͱ”
ࠩҟΛຒΊΔςΫχοΫ ͏·͘ߦ͖ͦ͏͚ͩͲͬ͘͠Γ͜ͳ͍ͭ
‣ ίϯτϩʔϥʔͰARϞσϧʹ٧Ί͢ɻ ‣ ͍ΘΏΔFat ControllerʹͳΓ͕ͪ ‣ ͷͰϞσϧʹدͤΔɺͱFat Model ‣ ·͍͍͋ͯ͑͠Ϟσϧ͕Ͱ͔͍΄͏͕·ͩϚγ…
ࠩҟΛຒΊΔςΫχοΫ
‣ accept_nested_attributes ͰҰ࿈ͷσʔλΛ ·ͱΊͯೖྗͤ͞Δ ‣ ϑΥʔϜίϯτϩʔϥʹɺӬଓԽͷσʔλάϥϑ͕࿐ग़͢Δ ‣ ͓͢͢Ί͠·ͤΜɻ ࠩҟΛຒΊΔςΫχοΫ
‣ ʮӬଓԽ͢Δ͚ͩʯͰͳ͍ॲཧΛίʔϧόοΫͱ࣮ͯ͠ݱ ͢Δɻ ‣ ίϧόοΫ͍ͨ͠ͱ͖ͱɺ୯ʹσʔλΛอଘ͍ͨ͠ͱ͖ͷหผ͕͍ͨΜ ‣ ίʔϧόοΫʹͨ͘͞Μͷ if ͕Ͱ͖ͯ͘Δͷ͕༧ஹ ࠩҟΛຒΊΔςΫχοΫ
‣ 7 Patterns to Refactor Fat ActiveRecord Models ‣ https://codeclimate.com/blog/7-ways-to-decompose-fat-
activerecord-models/ ‣Realworld Domain Model on Rails ‣ https://speakerdeck.com/joker1007/realworld-domain- model-on-rails ͍ͨΜͩΑͶɺɺɺͱ͍͏ͷ͕ΒΕ͖ͯͨ
͡Ί͔Β ͪΌΜͱ ઃܭ͢ΔͷΉ͔͍ͣ͠
ܧଓతʹҭͯΔҰา
“ ࠷༗༻ͳઃܭݪଇʹɺϓϩάϥϜʢϢʔ βʔΠϯλʔϑΣΠεʣͷϓϨθϯςʔγϣ ϯͱͦͷଞͷػೳΛ͏·͚͘Δɺͱ͍ ͏ͷ͕͋Γ·͢ɻ ϓϨθϯςʔγϣϯͱυϝΠϯͷ http://bliki-ja.github.io/PresentationDomainSeparation/
‣ Webͷೖྗ = request ʹू͞Ε͍ͯΔσʔλ ‣ ͱͦΕΛಋͨ͘ΊͷϑΥʔϜͦͷଞը໘ ‣ϦϯΫͰͷGETભҠೖྗͱ͍͑ೖྗ͚ͩͲɺ ͜͜Ͱ;Ε·ͤΜɻ ‣ඇಉظδϣϒͰ
AJ#perform ͷҾڥมͳͲ͕ ೖྗͱͳΔɻ RailsͷϓϨθϯςʔγϣϯ
‣ ʮͦͷଞͷػೳʯ ‣ 1ͭҎ্ͷςʔϒϧʹҰ࿈ͷσʔλΛ·ͱΊͯӬଓԽ͢Δ ‣ ࿈ܞγεςϜʹ͚ͯΠϕϯτΛPub͢Δ ‣ ͳͲͳͲ RailsͰ͍͏υϝΠϯ
‣ ϓϨθϯςʔγϣϯͷ͕ࣝɺʮͦͷଞͷػೳʯʹϦʔΫ ͠ͳ͍Α͏ʹɻ·ͣೖྗΛ͖ͬΓͤ͞Δɻ ʮ͏·͘ʯ͚Δ
‣ ίϯτϩʔϥʹͯparams͔ΒΛऔΓग़͠ɺHash จࣈྻͱͯ͠ѻ͏ɻ ‣ ࣮ଶ͕ AC::Parameters Ͱ Hash ͷΑ͏ʹѻ͏ɻ৺ͷͰܕΛݟΔ ‣
HTTP༝དྷͷσʔλɺrequest͔ΒऔΓग़͓ͯ͘͠ɻ ‣ #user_agent ͱ͔ɺΫοΩʔͷͱ͔ ೖྗΛ͖ͬΓ
‣ ొϖʔδͰϝʔϧΞυϨεΛೖྗͤ͞Δɻ ‣ ೖྗ͞ΕͨϝʔϧΞυϨεΛอଘ͢Δ ྫ: Ϣʔβʔొ
‣ ࣮ࡏ֬ೝ༻ͷURLτʔΫϯҰॹʹอଘ͢Δɻ ‣ ͜Ε after create ίʔϧόοΫͰΔ͜ͱଟ͍͠ɺͦΕ͚ͩͳΒ͞΄ͲࠔΒͳ͍͚Ͳɻ ‣ τʔΫϯΛؚΉURLΛϝʔϧͰૹ৴͢Δɻ ‣
͜ΕΛίʔϧόοΫͰΔͱՒࠜʹͳΓ͕ͪɻ ྫ: AR͚ͩͰ·͔ͳ͍ͮΒ͍ʮΔ͜ͱʯ
‣ ίϯτϩʔϥͰऔΓग़ͨͨͪ͠Λೖྗʹ͢Δɻ ‣ ୯Ұͷϝιουݺͼग़͠ͰॲཧҰࣜΛ࣮ߦ͢Δɻ ‣ ໊લΛ͚ͭΔͷ૬มΘΒ͍ͣ͠ ‣ ಈ໊ࢺʹͨ͠Γɺpre/suffix͚ͭͨΓɺͦͷଞنΛಋೖͨ͠Γɻɻɻ ‣ ؤுΕม͑ΒΕΔͷͰɺνʔϜͰͬ͘͠ΓདྷΔͭʹ͢ΔͱΑ͍ɻ
͚ΔͨΊͷΛಋೖ͢Δ(ศ্ٓϑΥʔϜΦϒδΣΫτͱݺͼ·͢)
“ • ಉ͡جຊϓϩάϥϜΛɺॏෳίʔυͳ͠ʹɺෳͷϓϨθϯςʔγϣϯʹ ରԠͤ͞Δ͜ͱ͕Ͱ͖Δ • ϢʔβʔΠϯλʔϑΣΠεςετ͕͠ʹ͍ͨ͘ΊɺͦΕΛ͢Δ͜ͱ ʹΑΓɺςετՄೳͳϩδοΫ෦ʹूதͰ͖Δ • εΫϦϓτ༻ͷ"1*αʔϏεͱͯ͠֎෦Խ͢ΔͨΊͷ"1*ΛָʹՃͰ ͖ΔʢબՄೳͳϓϨθϯςʔγϣϯ෦Ͱݟ͔͚Δʣ
ϓϨθϯςʔγϣϯͱυϝΠϯͷ http://bliki-ja.github.io/PresentationDomainSeparation/
‣ ͜ͷ”͚ΔͨΊͷ”ͷೖྗPOROʹͳΔͷͰɺςε τ͔Β؆୯ʹݺͼग़ͤΔɻ ‣ PORO: Plain Old Ruby Object =
ී௨ͷΦϒδΣΫτ ‣ ؆୯ʹݺͼग़ͤΔͷͰɺଞͷςετͰͷσʔληοτΞο ϓʹ͑Δɻ ςετՄೳ
email = '
[email protected]
' form = UserRegistrationForm.new(email: email) form.call token =
extract_token_from_sent_email(AM::Base.deliveries.last) expect(token).not_to be_nil expect(UserRegistration.find_by(email: email, uuid: token)).to be_present ྫ1: ೖྗ͞ΕͨϝΞυΛอଘͯ֬͠ೝURLΛϝʔϧ͢Δͷͷςετ
͜ͷʮϑΥʔϜΦϒδΣΫτʯΛߋʹɺͨͱ͑͜Μͳ;͏ʹҭͯͨ͘ͳͬͨͱͯ͠: 1. ϑΥʔϜΦϒδΣΫτೖྗϋϯυϦϯάʹͱͲΊɺ ӬଓԽͷͨΊʹαʔϏεΛ͏Ұઃ͚͍ͨɻ 2. ϝʔϧૹ৴ΤϯςΟςΟӬଓԽΛPub/SubͰݕͯ͠ ૄ݁߹ʹ͍ͨ͠ɻ “ϩδοΫ෦ʹूதͰ͖Δ”
> ӬଓԽͷͨΊʹαʔϏεΛઃ͚͍ͨ email = '
[email protected]
' form = UserRegistrationForm.new(email:
email) form.call token = extract_token_from_sent_email(AM::Base.deliveries.last) expect(token).not_to be_nil expect(UserRegistration.find_by(email: email, uuid: token)).to be_present ‣ ෦ʹ͏1ϨΠϠઃ͚ͯɺϓϨθϯςʔγϣϯͱͷΠϯ λʔϑΣʔεมΘΒͣ҆ఆ͍ͯ͠Δɻ
> Pub/SubͰૄ݁߹ʙ UserRegistrationForm.new(email: email).call + OurJob.execute_all! token =
extract_token_from_sent_email(AM::Base.deliveries.last) ‣ ΠϯλʔϑΣʔε҆ఆͨ͠··ɺΞʔΩςΫνϟมߋʹ ඞཁͳमਖ਼͚ͩΛೖΕΕΑ͍ɻ
‣ ΠϯλʔϑΣʔε͕҆ఆ͢ΔͷͰɺϩδοΫ෦Λ มԽ/ચ࿅͢Δࣗ༝͕ಘΒΕΔɻ ‣ (ಈ࡞͢Δ && !ΩϨΠ) ͳίʔυΛɺ (ಈ࡞͢Δ &&
ΩϨΠ) ͳίʔυʹҭͯΒΕΔɻ ‣ ϦϑΝΫλϦϯά! “ϩδοΫ෦ʹूதͰ͖Δ”
ศ্ٓϑΥʔϜΦϒδΣΫτͱݺΜͩ ҙਤ
‣ A: ͲͬͪͰ͍͍ ‣ ࣗಈςετ͕͋ͬͯϦϑΝΫλϦϯά͘͢͠ͳ͍ͬͯΕokɻ ‣ ʮೖྗΛͱΓ·ͱΊͯόϦσʔγϣϯ·ͰΛ͢Δʯͱɺ ʮͦͷvalidͳೖྗͰॲཧΛ͢Δʯʹׂ͍͍ͯ͠Μ͡Όͳ͍͔ͳɻ ‣ ࠷ॳʹখ͘͞࡞Δͱ͖UIͱ͚ۙͮͨ΄͏͕͍͍Μ͡Όͳ͍͔ͳ
‣ ʮϑΥʔϜʯͬͯͭ·ΓɺαʔϏεΛఏڙ͢Δଆ͕ར༻ऀʹظ͢Δ ߦಈͦͷͷͩΑͶɻ ‣ ͦ͜ʹԊͬͨͷΛ࡞Δͷ͕ૉ͡Όͳ͍͔ͳɻ αʔϏεϨΠϠ͡Όͳͯ͘ϑΥʔϜΦϒδΣΫτਪ͠ͳͷͳͥ?
‣ ʮೖྗʯͱʮϩδοΫ෦ʯΛ͚Α͏ ‣ ϓϩμΫτίʔυςετεοΩϦ͢Δͣ! ‣ ࠷ॳখ͘͞φΠʔϒʹ࡞Ζ͏ ‣ ઃܭ͕ΜΓ͗ͯ͢ർΕͳ͍Α͏ʹ… ‣ Ͳ͏͍͏நԽ͕ྑ͍ͷ͔ɺ࠷ॳΘ͔Βͳ͍͔ΒͶ
‣ ͪΌΜͱʑϦϑΝΫλϦϯά͠Α͏ ‣ φΠʔϒͳ··ΰνϟοͱੵΈଓ͚ΔͱͦΕμϝͰ͢Ͷ ͲͬͪͰΑ͘ͳ͍͜ͱ
·ͱΊ
‣ Ϗϡʔ / ίϯτϩʔϥ / AR::B ͷࡾ૬ߏͰ·͔ͳ͑ͳͦ͏ ͳ߹ɺബ͍Λ͏Ұ࡞ͬͯΈΔͱΑ͍ɻ ‣ ίϯτϩʔϥ͕ѻ͏WebͷೖྗͱɺϩδοΫʹඞཁͳ
ೖྗͷڥքͱͳΔ͜ͱΛҙࣝ͢Δɻ ‣ φΠʔϒ͔ͭςετ͕ॻ͖͍͢ϨΠϠ͔Β͡Ίͯɺ ෮͠ͳ͕ΒมԽ͍͚ͯ͠ΔΑ͏ʹ! ·ͱΊ