Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
実践 Rails アソシエーションリファクタリング / Rails association r...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Kei Shiratsuchi
PRO
October 22, 2022
Technology
10k
8
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
実践 Rails アソシエーションリファクタリング / Rails association refactoring in practice
Kaigi on Rails 2022
https://kaigionrails.org/2022/
https://kaigionrails.org/2022/talks/kei-s/
Kei Shiratsuchi
PRO
October 22, 2022
More Decks by Kei Shiratsuchi
See All by Kei Shiratsuchi
モノリスとマイクロサービスの橋渡し - ベターからモアベターへ
kei_s
PRO
0
140
なぜ リアーキテクティング専任チームを作ったのか
kei_s
PRO
2
1.7k
「Go言語でつくるインタプリタ」を Rust で移植してみた / "Write An Interpreter In Go" In Rust
kei_s
PRO
1
2.1k
Rust言語で作るインタプリタ / Write An Interpreter In Rust
kei_s
PRO
2
820
育児休業のご報告と、育児グッズとしてのスマートスピーカー / Parental Leave and SmartSpeaker
kei_s
PRO
0
910
「深層学習による自然言語処理」読書会 第6章2.7
kei_s
PRO
0
500
「深層学習による自然言語処理」読書会 第5章5.1
kei_s
PRO
0
510
最近個人的に気になるプログラミング言語おさらい Ruby, Python, Go, Rust, Julia
kei_s
PRO
0
1.1k
「深層学習による自然言語処理」読書会 第2章2.1~2.5
kei_s
PRO
0
510
Other Decks in Technology
See All in Technology
3人で1000GPU超を統合運用する?マルチクラウド&オンプレを跨ぐ、構築と運用のリアル!
kazukun0716
2
510
猫でもわかるKiro Web
kentapapa
1
120
CI/CDではもう遅い - 人とAIが迂回しないDevSecOps Verify基盤の再設計 -
kintotechdev
1
340
作って終わりじゃないサーバーレス 〜9年運用する大規模EC物流API基盤の設計・運用のリアル〜
zozotech
PRO
0
560
AIエージェント時代のPlatform as a Product —— テックリードがPdMとして回す発見・導入・計測 / Platform as a Product in the AI Agent Era
toshi0607
1
400
10年欲しかった音楽管理アプリを、AIと一緒に作りはじめた
judau
1
150
JSONataとAWS Step Functionsで目指すRuntimelessな世界
mu7889yoon
1
530
Datadog で始める トークンセーフティなAI 導⼊と定着
vkbaba
1
110
覗いてみよう 関数型ビジュアル言語×2Dグラフィックスの世界
yohyamasaki
0
130
DORA_Metrics.pdf
wagnerfusca
1
110
特殊変数大全
dak2
0
150
AIに書かせて、プラットフォームで縛る ― EKSプラットフォームで実践した責任境界と権限設計
elmodev09
0
830
Featured
See All Featured
Discover your Explorer Soul
emna__ayadi
2
1.3k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.1k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
550
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
58k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
690
Git: the NoSQL Database
bkeepers
PRO
432
67k
Faster Mobile Websites
deanohume
310
32k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.7k
エンジニアに許された特別な時間の終わり
watany
109
250k
Amusing Abliteration
ianozsvald
1
320
Joys of Absence: A Defence of Solitary Play
codingconduct
1
530
The SEO identity crisis: Don't let AI make you average
varn
0
560
Transcript
࣮ફ Rails ΞιγΤʔγϣϯ ϦϑΝΫλϦϯά നܛ, Kei Shiratsuchi, @kei_s Kaigi on
Rails 2022, 2022.10.22(Sat)
Πϯτϩ • Day 1 ͷ @pndcat ͞ΜʹΑΔʰཏສʹʮ͍͍Ͷʯ͢ΔͨΊͷ σʔλߏ ʱͷɺٯํͷϦϑΝΫλϦϯάͷΛ͠·͢ •
ϙϦϞʔϑΟοΫؔ࿈Λதؒςʔϒϧ • ͲͪΒɺཧ༝͕͋ͬͯҙຯ͕͋Δɺͱ͍͏͜ͱΛ࣋ͬͯ ؼ͍͚ͬͯͨͩΕ 🙏 • ͲͪΒ࠾༻͍͍ͯͨͩͨ͠ Kaigi on Rails νʔϜ͍͢͝ 👏
ࣗݾհ • നɹܛʢγϥπνɹέΠʣ • : kei-s, : @kei_s • ANDPAD
גࣜձࣾ Tech Lead • ॳΊͯ rails new ͔ͯ͠Β 15 ͘Β͍ • ࠓ Kaigi on Rails ͷୗࣇαϙʔτΛར༻ͤͯ͞Β͍ͬͯ·͢ • ͱͯྑ͍औΓΈͰײँ͍ͯ͠·͢ʂ
എܠ
લఏ • ANDPAD : ݐஙɺݐઃۀ͚ͷ SaaS • த৺ͱͳΔҰͭͷ Rails ΞϓϦͰɺෳͷۀυϝΠϯͷόο
ΫΤϯυΛఏڙ͍ͯ͠Δ • ࢪཧɺݕࠪɺνϟοτɺetc… • ͦΕͧΕͷυϝΠϯʹ։ൃνʔϜ͕͋Δ • ͦΕΒͷνʔϜ͕Ұͭͷ Rails ΞϓϦʹରͯ͠ػೳ։ൃͯ͠ ͍Δ
എܠ • ෳͷυϝΠϯͷػೳ͕૬Γ͍ͯ͠ΔͨΊɺRails ΞϓϦ͔ͳΓେنʹͳͬ ͍ͯΔ • Day 1 ͷ makicamel
͞ΜͷൃදΛࢀর͍ͩ͘͞ • ͜ͷ Rails ΞϓϦͰɺϙϦϞʔϑΟοΫؔ࿈͕ଟ༻͞Ε͍ͯΔ • ಛʹʮࣸਅʯʮࢿྉʯͳͲɺ͍ΘΏΔετοΫσʔλͷؔ࿈͚ʹ༻͍Β Ε͍ͯΔ • ͜ΕΒͷσʔλɺυϝΠϯΛލ͍Ͱར༻͞Ε͍ͯΔ • ͋ΔυϝΠϯͰ࡞͞ΕͨσʔλΛɺผͷυϝΠϯ͔ΒࢀরͰ͖Δ • ྫɿࢪཧͰΞοϓϩʔυͨࣸ͠ਅΛɺνϟοτʹషΓ͚Δ
ϙϦϞʔϑΟοΫؔ࿈ͱ • ҰͭͷϞσϧΛෳͷϞσϧʹඥ͚ͮΔ • *_type ΧϥϜʹϞσϧͷΫϥε໊Λ อଘ͢Δ • ར: ͋ΒΏΔϞσϧʹඥ͚ͮΔ͜ͱ͕
Ͱ͖Δ • ઃܭ࣌ʹଘࡏ͠ͳ͔ͬͨϞσϧͱ ඥ͚ͮΒΕΔ • ܽ: DBͰ֎෦ΩʔΛઃఆͰ͖ͳ͍ class Picture < ApplicationRecord belongs_to :imageable, polymorphic: true end class Employee < ApplicationRecord has_many :pictures, as: :imageable end class Product < ApplicationRecord has_many :pictures, as: :imageable end @employee.pictures # = > [#<Picture: . . >, . . ] @product.pictures # = > [#<Picture: . . >, . . ]
Ұ൪ͷͭΒΈ • σʔλϞσϧͷॴ༗ʹϙϦϞʔϑΟο Ϋؔ࿈ • σʔλϞσϧͷࢀরʹϙϦϞʔϑΟο Ϋؔ࿈ • ສͱສΛؔ࿈ͤ͞Δ͜ͱ͕Ͱ͖ ͯศརʢຊʹ…???ʣ
• ࣮ࡍʹɺॴ༗ͱࢀরͰ͍͚Δϝ Ϧοτ͕ͳ͍ ॴ༗ ࢀর
Կ͕ى͖͍͔ͯͨ • ؔ࿈͚ͷશ༰Ѳ͕͍͠ • σʔλΛͲ͔͜Βར༻͍ͯ͠Δ͔͕໌ࣔతͰͳ͍ • σʔλϞσϧଆʹఆ͕ٛͳ͘ɺಈ࡞ͷதͰ͔͠ݱΕͳ͍ • σʔλΛར༻͢Δ৽ػೳͰɺ࠷దͳ࣮͕Θ͔Βͳ͍ͨ Ίطଘ࣮Λ౿ऻ͠ɺෳࡶ͕͞૿େ͍ͯ͘͠
• υϝΠϯΛލ͍Ͱར༻͞Ε͍ͯΔͨΊมߋͷӨڹൣғ͕େ ͖͘ɺ֤υϝΠϯͷ։ൃνʔϜͰमਖ਼͕͍͠
ਅͷ՝ • কདྷతʹɺେنRailsΞϓϦΛ υϝΠϯ͝ͱʹղମ͍͖͍ͯͨ͠ • ۩ମతͳಓے To Be Determined
• υϝΠϯΛލ͍ͰΘΕΔσʔλ ͷѻ͍ඞͣ՝ʹͳΔ • શ༰͕ѲͰ͖ͳ͍ෳࡶͳ࣮Λ ղফ͢Δඞཁ͕͋Δ Rails ΞϓϦ ࢪཧ νϟοτ ࣸਅ Ϟσϧ Ϟσϧ ϚΠΫϩαʔϏεʁ ϞδϡϥϞϊϦεʁ
ϦϑΝΫλϦϯάํ • ϙϦϞʔϑΟοΫؔ࿈Λɺதؒ ςʔϒϧʹΑΔؔ࿈͚ʹஔ͖ ͑Δ • ؔ࿈͚Λ໌ࣔͰ͖Δ • ॻ੶ʮSQLΞϯνύλʔϯʯͰ հ͞Ε͍ͯΔख๏
class Photo < ApplicationRecord has_many :message_photos has_many :messages, through: :message_photos end class MessagePhoto < ApplicationRecord belongs_to :message belongs_to :photo end class Message < ApplicationRecord has_many :message_photos has_many :photos, through: :message_photos end
େنΞϓϦͳΒͰͷ • ϝϯςφϯελΠϜΛઃ͚ͣʹਐΊ͍ͨ • มߋՕॴ͕ଟ͍ͨΊɺఀΊΔͷඇݱ࣮త • Ҡߦதʹෆ۩߹͕ൃ֮ͨ͠ΒΓ͍ͨ͠͠ • ҠߦՕॴ͕ཏ͠Ε͍ͯΔ͔ෆ҆ •
ࣗಈςετͰΧόʔͰ͖͍ͯͳ͍Օॴ͕͋ΔͷͰ ͳ͍͔
ϦϑΝΫλϦϯάͷ࣮ࢪ
ҠߦܭըͰॏࢹ͢ΔϙΠϯτ • ແఀࢭͰߦ͏ • ՄೳͳݶΓ҆શʹߦ͏ • ͙͢ʹΓ͕͠Ͱ͖ΔΑ͏ʹ͢Δ • → ৽چΞιγΤʔγϣϯͷಉ࣌ॻ͖ࠐΈ
• Ҡߦ͖͠Δ • Ҡߦ࿙ΕΛ์ஔ͠ͳ͍͜ͱ • → ϓϩμΫγϣϯڥͰൈ͚࿙Ε͕ͳ͍͔ݕ
ҠߦͷྲྀΕ • 4ճͷϦϦʔε🚀ɺ2ճͷσʔλमਖ਼📝Λߦ͏ 1. 🚀 ҠߦઌϞσϧ࡞ɺچˠ৽ͷಉ࣌ॻ͖ࠐΈ 2. 📝 طଘσʔλΛ৽ΞιγΤʔγϣϯʹొ 3.
🚀 ৽ΞιγΤʔγϣϯʹஔ͖͑ɺ৽ˠچͷಉ࣌ॻ͖ࠐΈ 4. 🚀 ൈ͚࿙Εݕ 5. 🚀 ্͛ 6. 📝 چσʔλΛআ
1. 🚀 ҠߦઌϞσϧ࡞ɺچˠ৽ͷಉ࣌ॻ͖ࠐΈ • ҠߦઌͱͳΔதؒςʔϒϧΛ࡞͢Δ • ৽ΞιγΤʔγϣϯΛɺچΞιγΤʔγϣϯͱผ໊Ͱੜ͢ • after_create ίʔϧόοΫͰɺچΞιγΤʔγϣϯ͕࡞͞ΕͨΒ৽ΞιγΤʔ
γϣϯΛಉ࣌ʹ࡞͢Δ • ඞཁʹΑͬͯɺߋ৽ɾআ͞ΕΔ߹ରԠ • 👉 ͜Ε͔ΒՃ͞ΕΔσʔλ৽چͰಉظ͞ΕΔ class Message < ApplicationRecord has_many :photos, as: :imageable has_many :message_photos has_many :renewed_photos, through: :message_photos, source: :photo end class Photo < ApplicationRecord belongs_to :imageable, polymorphic: true has_many :message_photos has_many :messages, through: :message_photos after_create :create_message_photos!, if: - > { imageable.is_a?(Message) } def create_message_photos! message_photos.create!(message: imageable) end end
2. 📝 طଘσʔλΛ৽ΞιγΤʔγϣϯʹొ • چΞιγΤʔγϣϯʹΑΔطଘσʔλΛಡΈग़͠ɺ৽ ΞιγΤʔγϣϯʹొ͢ΔόονॲཧΛ࣮ߦ͢Δ • 👉 શͯͷσʔλ͕৽چͰಉظ͞ΕΔ
3. 🚀 ৽ΞιγΤʔγϣϯʹஔ͖͑ɺ৽ˠچͷಉ࣌ॻ͖ࠐΈ • ผ໊Ͱ࡞ͨ͠৽ΞιγΤʔγϣϯΛར༻͢ΔΑ͏मਖ਼͢Δ • ৽ΞιγΤʔγϣϯΛͬͯɺγϯϓϧͳ࣮Λ͢Δ • ࡞ɾߋ৽ՕॴϑΟʔνϟʔτάϧͰΓͤΔΑ͏ʹ͢Δ •
৽ˠچͷಉ࣌ॻ͖ࠐΈΛ࣮͢Δ • ࡞࣌ʹ *_type ͱ *_id ΛదʹຒΊΔ • چˠ৽ͷಉ࣌ॻ͖ࠐΈఀࢭͤͣҡ࣋͢Δ • ஔ͖͑ʹൈ͚͕͋ͬͨ߹Γͨ͠͠߹ʹ͕ى͖ͳ͍Α͏ʹ • 👉 ·ͩɺશͯͷσʔλ͕৽چͰಉظ͞ΕΔ
4. 🚀 ൈ͚࿙Εݕ • چΞιγΤʔγϣϯ͕ར༻͞ΕͨΒɺϩάΛग़ྗͤ͞Δ • extend: Φϓγϣϯʹϩά༻ϞδϡʔϧΛ͠ɺϞδϡʔϧͷ self.extended ͕ൃ
Րͨ͠ΒɺͲ͔͜ͰΠϯελϯεԽ͞Εͨͣ • ϩάʹ backtrace Λग़͠ɺͲ͔͜ΒݺΕ͔ͨΛௐࠪ͢Δ • 👉 ϓϩμΫγϣϯͰϩά͕ग़Δ͔Ұఆظ༷ؒࢠΛݟΔ class Message < ApplicationRecord has_many :photos, as: :imageable, extend: LoggingLeakage end module LoggingLeakage def self.extended(obj) # ผʑͷ obj Ͱ3ճݺͼग़͞ΕΔͨΊɺҰ͚࣮ͩߦ͞ΕΔΑ͏ʹ͢Δ return if obj.class.to_s ! = 'Photo : : ActiveRecord_Associations_CollectionProxy' backtrace = caller.grep(/ # { Regexp.escape(Rails.root.to_s)}/) leakage_logger.info "Replace leakage detected. # { backtrace}" end end
5. 🚀 ্͛ • چΞιγΤʔγϣϯΛআ • ৽ΞιγΤʔγϣϯΛผ໊͔Βຊདྷͷ໊લʹมߋ • ৽ˠچͷಉ࣌ॻ͖ࠐΈͷఀࢭ •
👉 ظ͢ΔίʔυͰͷಈ࡞͕։࢝
6. 📝 چσʔλΛআ • ϙϦϞʔϑΟοΫؔ࿈༻ͷΧϥϜʢ*_type, *_idʣΛ null Ͱ ຒΊΔ •
ରԠ͕ྃͨ͜͠ͱΛࣔͨ͢Ί • 👉 Ҡߦྃʂ
Ͳ͏࣮ͬͯࢪ͍ͯ͠Δ͔
ઐνʔϜ • ϦΞʔΩςΫςΟϯάνʔϜͱ໋໊͞Ε ͨɺυϝΠϯΛԣஅ͢ΔՕॴͷվળΛߦ ͏νʔϜ • طଘͷΈͷͭΒ͍෦Λղফ͠ɺ ͓खຊͱͳΔΑ͏ͳͷΛ࡞Δ • ։ൃνʔϜશମͰɺվળ׆ಈΛܧଓ͠
ͯΔͧɺͱ͍͏จԽΛৢ͍ͨ͠ • ·ͣσʔλϞσϧपΓͷΞιγΤʔ γϣϯվળʹணख Rails ΞϓϦ ࢪཧ νϟοτ ࣸਅ Ϟσϧ Ϟσϧ
εύΠΫίʔυͷॏཁੑ • ࣮ࡍʹҠߦΛ࢝ΊΔલʹɺҠߦεςοϓͷશͯΛ࣮ͯ͠ΈΔ • ࣮ࣺͯͯྑ͍ • ·Ͱͷෆ֬ఆཁૉΛશͯ௵͓ͯ͘͠ • ໎͏ͱ͜ΖΛϖΞϓϩͳͲͰղܾ͢Δ •
ʮௐࠪʯͱʮ࣮ࢪʯͰϑΣʔζΛ͚Δ • εύΠΫ࡞ۀͷݟੵΓ͍͕͠ɺ࣮ࡍͷҠߦ࡞ۀݟੵΓ͕͠ ͍͢ • ʮ࣮ࢪʯظؒதʹɺผՕॴͷʮௐࠪʯΛฒߦͰ͖Δ
ࡉ͔ͳ Tipsʢ࣌ؒతʹׂѪʣ • ΞιγΤʔγϣϯʹ dependent: :destroy ͕͋Δ߹ɺಈ࡞͕มΘΔ • ϙϦϞʔϑΟοΫؔ࿈ͰࢠϞσϧআ͞ΕΔ͕ɺதؒςʔϒϧؔ࿈Ͱ ɺதؒཁૉϞσϧͷΈআ͞ΕΔ
• callback ͳͲͰࢠϞσϧআ͢ΔΑ͏ʹ͢Δ • چˠ৽ͱ৽ˠچͷಉ࣌ॻ͖ࠐΈ͕྆ํଘࡏ͢ΔλΠϛϯά͕͋ΔͨΊɺೋॏʹ ൃՐ͢ΔͷΛճආ͢Δ • อଘ࣌ʹ :skip_double_write ͷΑ͏ͳ attribute Λੜ੍ͯ͠ޚ͢Δ • ൈ͚࿙Εݕͷϩάಉ͡ՕॴͰଟྔʹग़ΔՄೳੑ͕͋ΔͨΊɺ1ϦΫΤετͰ ॏෳ͢ΔϩάΛ uniq ͢ΔػߏΛࠐΉ
·ͱΊ • σʔλϞσϧઃܭΛஔ͖͑Δͷ݁ߏେม • ՄೳͳݶΓϦϦʔεલʹݕ౼͠Α͏…! • ͱ͍͑ɺॳఆͱมΘΔ͜ͱ͋ΓಘΔ • ෳࡶͰྑ͘ͳ͍෦ɺ์ஔ͍ͯ͠Δͱ૿͑Δ •
ෳࡶͰ͍͔͠Βͦ͜ɺલྫΛ౿ऻͯ͠͠·͏ • ϦϑΝΫλϦϯάʹΑͬͯʮՁΛఏڙ͠ଓ͚Δʯʹد༩͢Δ • ʮ͠ଓ͚ΔʯͨΊʹɺ͔Γ͘͢ɺखΛೖΕ͘͢อͭ