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
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
越境するなら専門用語を使うな高校校歌 / If you wanna cross border, you shouldn't use jargon
vtryo
0
130
AI 時代のスタートアップエコシステ厶から考究する技術的負債との向き合い方
m3m0r7
PRO
2
1.4k
SQL文一行も書けない人事がCortexもろもろを使って人事業務を楽にしてみる
ponponmikankan
1
240
range over func 2年間の軌跡 Issue #56413 はGoのエコシステムをどう変えたか
ryujicre8ive
0
160
Deploying a Full-Stack Bun-Native Framework on Cloudflare Workers
7nohe
0
160
AI時代、データエンジニアが一番おもろい
genshun9
0
510
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
3
490
Adaptive Warehouse を今すぐ導入すべき理由と迷ったときの判断基準
__allllllllez__
0
220
山手線を徒歩で一周してわかった、 位置情報アプリは「足」が最強のデバッガー
hinakko
0
140
The Agent Builder Loop from Daily Work to OSS
minorun365
PRO
3
170
積み重なった技術負債への挑戦 〜初手としての全社ゴト化〜
techtekt
PRO
0
630
Sigmaユーザーのための有用リソース一挙公開 & Sigmaで使えるMCP #sigma_ucj /useful-resources-for-sigma-computing-users-and-mcps-with-sigma
shinyaa31
0
220
Featured
See All Featured
Test your architecture with Archunit
thirion
2
2.4k
The Limits of Empathy - UXLibs8
cassininazir
1
660
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
190
A Soul's Torment
seathinner
7
3.6k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
580
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
KATA
mclloyd
PRO
35
15k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
Accessibility Awareness
sabderemane
1
210
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
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 ͢ΔػߏΛࠐΉ
·ͱΊ • σʔλϞσϧઃܭΛஔ͖͑Δͷ݁ߏେม • ՄೳͳݶΓϦϦʔεલʹݕ౼͠Α͏…! • ͱ͍͑ɺॳఆͱมΘΔ͜ͱ͋ΓಘΔ • ෳࡶͰྑ͘ͳ͍෦ɺ์ஔ͍ͯ͠Δͱ૿͑Δ •
ෳࡶͰ͍͔͠Βͦ͜ɺલྫΛ౿ऻͯ͠͠·͏ • ϦϑΝΫλϦϯάʹΑͬͯʮՁΛఏڙ͠ଓ͚Δʯʹد༩͢Δ • ʮ͠ଓ͚ΔʯͨΊʹɺ͔Γ͘͢ɺखΛೖΕ͘͢อͭ