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
1.9k
フォームオブジェクトとの向き合い方/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
6
10k
Simplicity on Rails -- RDB, REST and Ruby
moro
14
16k
ちょうどよい Rails E2E テスト/enough-good-rails-e2e-test
moro
5
2.3k
フレームワークを作らない方法/How NOT to build frameworks
moro
4
1.1k
全体がいい感じになるために、私たちRailsをホームにするWeb技術者ができること/let-our-whole-system-grow
moro
2
1.8k
チームによるいきいきとしたソフトウェア開発/an-alive-team-grows-software
moro
3
3.3k
Web-E2E-Testing-from-Ruby
moro
5
500
Joyful user foundation restructuring with Ruby
moro
9
19k
cookpad-17day-tech-internship-2017-git
moro
0
9.4k
Other Decks in Programming
See All in Programming
タクシーアプリ『GO』のリアルタイムデータ分析基盤における機械学習サービスの活用
mot_techtalk
4
1.4k
LLM生成文章の精度評価自動化とプロンプトチューニングの効率化について
layerx
PRO
2
190
ローコードSaaSのUXを向上させるためのTypeScript
taro28
1
610
AWS IaCの注目アップデート 2024年10月版
konokenj
3
3.3k
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
Amazon Qを使ってIaCを触ろう!
maruto
0
400
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
Tauriでネイティブアプリを作りたい
tsucchinoko
0
370
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
310
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
1
290
シールドクラスをはじめよう / Getting Started with Sealed Classes
mackey0225
4
640
Amazon Bedrock Agentsを用いてアプリ開発してみた!
har1101
0
330
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
520
39k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
Into the Great Unknown - MozCon
thekraken
32
1.5k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
Scaling GitHub
holman
458
140k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
How to Ace a Technical Interview
jacobian
276
23k
Become a Pro
speakerdeck
PRO
25
5k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
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ͷೖྗͱɺϩδοΫʹඞཁͳ
ೖྗͷڥքͱͳΔ͜ͱΛҙࣝ͢Δɻ ‣ φΠʔϒ͔ͭςετ͕ॻ͖͍͢ϨΠϠ͔Β͡Ίͯɺ ෮͠ͳ͕ΒมԽ͍͚ͯ͠ΔΑ͏ʹ! ·ͱΊ