Slide 1

Slide 1 text

࣮ફ Rails ΞιγΤʔγϣϯ ϦϑΝΫλϦϯά ന౔ܛ, Kei Shiratsuchi, @kei_s Kaigi on Rails 2022, 2022.10.22(Sat)

Slide 2

Slide 2 text

Πϯτϩ • Day 1 ͷ @pndcat ͞ΜʹΑΔʰ৿ཏສ৅ʹʮ͍͍Ͷʯ͢ΔͨΊͷ σʔλߏ଄ ʱͷɺٯํ޲ͷϦϑΝΫλϦϯάͷ࿩Λ͠·͢ • ϙϦϞʔϑΟοΫؔ࿈Λதؒςʔϒϧ΁ • ͲͪΒ΋ɺཧ༝͕͋ͬͯҙຯ͕͋Δɺͱ͍͏͜ͱΛ࣋ͬͯ ؼ͍͚ͬͯͨͩΕ͹ 🙏 • ͲͪΒ΋࠾༻͍͍ͯͨͩͨ͠ Kaigi on Rails νʔϜ͍͢͝ 👏

Slide 3

Slide 3 text

ࣗݾ঺հ • ന౔ɹܛʢγϥπνɹέΠʣ • : kei-s, : @kei_s • ANDPAD גࣜձࣾ Tech Lead • ॳΊͯ rails new ͔ͯ͠Β 15 ೥͘Β͍ • ࠓ೔͸ Kaigi on Rails ͷୗࣇαϙʔτΛར༻ͤͯ͞΋Β͍ͬͯ·͢ • ͱͯ΋ྑ͍औΓ૊ΈͰײँ͍ͯ͠·͢ʂ

Slide 4

Slide 4 text

എܠ

Slide 5

Slide 5 text

લఏ • ANDPAD : ݐஙɺݐઃۀ޲͚ͷ SaaS • த৺ͱͳΔҰͭͷ Rails ΞϓϦͰɺෳ਺ͷۀ຿υϝΠϯͷόο ΫΤϯυΛఏڙ͍ͯ͠Δ • ࢪ޻؅ཧɺݕࠪɺνϟοτɺetc… • ͦΕͧΕͷυϝΠϯʹ։ൃνʔϜ͕͋Δ • ͦΕΒͷνʔϜ͕Ұͭͷ Rails ΞϓϦʹରͯ͠ػೳ։ൃͯ͠ ͍Δ

Slide 6

Slide 6 text

എܠ • ෳ਺ͷυϝΠϯͷػೳ͕૬৐Γ͍ͯ͠ΔͨΊɺRails ΞϓϦ͸͔ͳΓେن໛ʹͳͬ ͍ͯΔ • Day 1 ͷ makicamel ͞ΜͷൃදΛࢀর͍ͩ͘͞ • ͜ͷ Rails ΞϓϦͰɺϙϦϞʔϑΟοΫؔ࿈͕ଟ༻͞Ε͍ͯΔ • ಛʹʮࣸਅʯ΍ʮࢿྉʯͳͲɺ͍ΘΏΔετοΫσʔλͷؔ࿈෇͚ʹ༻͍Β Ε͍ͯΔ • ͜ΕΒͷσʔλ͸ɺυϝΠϯΛލ͍Ͱར༻͞Ε͍ͯΔ • ͋ΔυϝΠϯͰ࡞੒͞ΕͨσʔλΛɺผͷυϝΠϯ͔ΒࢀরͰ͖Δ • ྫɿࢪ޻؅ཧͰΞοϓϩʔυͨࣸ͠ਅΛɺνϟοτʹషΓ෇͚Δ

Slide 7

Slide 7 text

ϙϦϞʔϑΟοΫؔ࿈ͱ͸ • ҰͭͷϞσϧΛෳ਺ͷϞσϧʹඥ͚ͮΔ • *_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 # = > [#, . . ] @product.pictures # = > [#, . . ]

Slide 8

Slide 8 text

Ұ൪ͷͭΒΈ • σʔλϞσϧͷॴ༗ʹϙϦϞʔϑΟο Ϋؔ࿈ • σʔλϞσϧͷࢀরʹϙϦϞʔϑΟο Ϋؔ࿈ • ສ෺ͱສ෺Λؔ࿈ͤ͞Δ͜ͱ͕Ͱ͖ ͯศརʢຊ౰ʹ…???ʣ • ࣮ࡍʹ͸ɺॴ༗ͱࢀরͰ࢖͍෼͚Δϝ Ϧοτ͕ͳ͍ ॴ༗ ࢀর

Slide 9

Slide 9 text

Կ͕ى͖͍͔ͯͨ • ؔ࿈෇͚ͷશ༰೺Ѳ͕೉͍͠ • σʔλΛͲ͔͜Βར༻͍ͯ͠Δ͔͕໌ࣔతͰͳ͍ • σʔλϞσϧଆʹఆ͕ٛͳ͘ɺಈ࡞ͷதͰ͔͠ݱΕͳ͍ • σʔλΛར༻͢Δ৽ػೳͰɺ࠷దͳ࣮૷͕Θ͔Βͳ͍ͨ Ίطଘ࣮૷Λ౿ऻ͠ɺෳࡶ͕͞૿େ͍ͯ͘͠ • υϝΠϯΛލ͍Ͱར༻͞Ε͍ͯΔͨΊมߋͷӨڹൣғ͕େ ͖͘ɺ֤υϝΠϯͷ։ൃνʔϜͰ͸मਖ਼͕೉͍͠

Slide 10

Slide 10 text

ਅͷ՝୊ • কདྷతʹɺେن໛RailsΞϓϦΛ 
 υϝΠϯ͝ͱʹղମ͍͖͍ͯͨ͠ • ۩ମతͳಓے͸ To Be Determined • υϝΠϯΛލ͍Ͱ࢖ΘΕΔσʔλ ͷѻ͍͸ඞͣ՝୊ʹͳΔ • શ༰͕೺ѲͰ͖ͳ͍ෳࡶͳ࣮૷Λ ղফ͢Δඞཁ͕͋Δ Rails ΞϓϦ ࢪ޻؅ཧ νϟοτ ࣸਅ Ϟσϧ Ϟσϧ ϚΠΫϩαʔϏεʁ ϞδϡϥϞϊϦεʁ

Slide 11

Slide 11 text

ϦϑΝΫλϦϯάํ਑ • ϙϦϞʔϑΟοΫؔ࿈Λɺதؒ ςʔϒϧʹΑΔؔ࿈෇͚ʹஔ͖׵ ͑Δ • ؔ࿈෇͚Λ໌ࣔͰ͖Δ • ॻ੶ʮ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

Slide 12

Slide 12 text

େن໛ΞϓϦͳΒͰ͸ͷ೉఺ • ϝϯςφϯελΠϜΛઃ͚ͣʹਐΊ͍ͨ • มߋՕॴ͕ଟ͍ͨΊɺ౎౓ఀΊΔͷ͸ඇݱ࣮త • Ҡߦதʹෆ۩߹͕ൃ֮ͨ͠Β੾Γ໭͍ͨ͠͠ • ҠߦՕॴ͕໢ཏ͠੾Ε͍ͯΔ͔ෆ҆ • ࣗಈςετͰΧόʔͰ͖͍ͯͳ͍Օॴ͕͋ΔͷͰ͸ ͳ͍͔

Slide 13

Slide 13 text

ϦϑΝΫλϦϯάͷ࣮ࢪ

Slide 14

Slide 14 text

ҠߦܭըͰॏࢹ͢ΔϙΠϯτ • ແఀࢭͰߦ͏ • ՄೳͳݶΓ҆શʹߦ͏ • ͙͢ʹ੾Γ໭͕͠Ͱ͖ΔΑ͏ʹ͢Δ • → ৽چΞιγΤʔγϣϯͷಉ࣌ॻ͖ࠐΈ • Ҡߦ͖͠Δ • Ҡߦ࿙ΕΛ์ஔ͠ͳ͍͜ͱ • → ϓϩμΫγϣϯ؀ڥͰൈ͚࿙Ε͕ͳ͍͔ݕ஌

Slide 15

Slide 15 text

ҠߦͷྲྀΕ • 4ճͷϦϦʔε🚀ɺ2ճͷσʔλमਖ਼📝Λߦ͏ 1. 🚀 ҠߦઌϞσϧ࡞੒ɺچˠ৽ͷಉ࣌ॻ͖ࠐΈ 2. 📝 طଘσʔλΛ৽ΞιγΤʔγϣϯʹొ࿥ 3. 🚀 ৽ΞιγΤʔγϣϯʹஔ͖׵͑ɺ৽ˠچͷಉ࣌ॻ͖ࠐΈ 4. 🚀 ൈ͚࿙Εݕ஌ 5. 🚀 ࢓্͛ 6. 📝 چσʔλΛ࡟আ

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

2. 📝 طଘσʔλΛ৽ΞιγΤʔγϣϯʹొ࿥ • چΞιγΤʔγϣϯʹΑΔطଘσʔλΛಡΈग़͠ɺ৽ ΞιγΤʔγϣϯʹొ࿥͢ΔόονॲཧΛ࣮ߦ͢Δ • 👉 શͯͷσʔλ͕৽چͰಉظ͞ΕΔ

Slide 18

Slide 18 text

3. 🚀 ৽ΞιγΤʔγϣϯʹஔ͖׵͑ɺ৽ˠچͷಉ࣌ॻ͖ࠐΈ • ผ໊Ͱ࡞੒ͨ͠৽ΞιγΤʔγϣϯΛར༻͢ΔΑ͏मਖ਼͢Δ • ৽ΞιγΤʔγϣϯΛ࢖ͬͯɺγϯϓϧͳ࣮૷Λ͢Δ • ࡞੒ɾߋ৽Օॴ͸ϑΟʔνϟʔτάϧͰ੾Γ໭ͤΔΑ͏ʹ͢Δ • ৽ˠچͷಉ࣌ॻ͖ࠐΈΛ࣮૷͢Δ • ࡞੒࣌ʹ *_type ͱ *_id Λద੾ʹຒΊΔ • چˠ৽ͷಉ࣌ॻ͖ࠐΈ͸ఀࢭͤͣҡ࣋͢Δ • ஔ͖׵͑ʹൈ͚͕͋ͬͨ৔߹΍੾Γ໭ͨ͠͠৔߹ʹ໰୊͕ى͖ͳ͍Α͏ʹ • 👉 ·ͩɺશͯͷσʔλ͕৽چͰಉظ͞ΕΔ

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

5. 🚀 ࢓্͛ • چΞιγΤʔγϣϯΛ࡟আ • ৽ΞιγΤʔγϣϯΛผ໊͔Βຊདྷͷ໊લʹมߋ • ৽ˠچͷಉ࣌ॻ͖ࠐΈͷఀࢭ • 👉 ظ଴͢ΔίʔυͰͷಈ࡞͕։࢝

Slide 21

Slide 21 text

6. 📝 چσʔλΛ࡟আ • ϙϦϞʔϑΟοΫؔ࿈༻ͷΧϥϜʢ*_type, *_idʣΛ null Ͱ ຒΊΔ • ରԠ͕׬ྃͨ͜͠ͱΛࣔͨ͢Ί • 👉 Ҡߦ׬ྃʂ

Slide 22

Slide 22 text

Ͳ͏΍࣮ͬͯࢪ͍ͯ͠Δ͔

Slide 23

Slide 23 text

ઐ೚νʔϜ • ϦΞʔΩςΫςΟϯάνʔϜͱ໋໊͞Ε ͨɺυϝΠϯΛԣஅ͢ΔՕॴͷվળΛߦ ͏νʔϜ • طଘͷ࢓૊ΈͷͭΒ͍෦෼Λղফ͠ɺ ͓खຊͱͳΔΑ͏ͳ΋ͷΛ࡞Δ • ։ൃνʔϜશମͰɺվળ׆ಈΛܧଓ͠ ͯ΍Δͧɺͱ͍͏จԽΛৢ੒͍ͨ͠ • ·ͣ͸σʔλϞσϧपΓͷΞιγΤʔ γϣϯվળʹணख Rails ΞϓϦ ࢪ޻؅ཧ νϟοτ ࣸਅ Ϟσϧ Ϟσϧ

Slide 24

Slide 24 text

εύΠΫίʔυͷॏཁੑ • ࣮ࡍʹҠߦΛ࢝ΊΔલʹɺҠߦεςοϓͷશͯΛ࣮૷ͯ͠ΈΔ • ࣮૷͸ࣺͯͯ΋ྑ͍ • ׬੒·Ͱͷෆ֬ఆཁૉΛશͯ௵͓ͯ͘͠ • ໎͏ͱ͜ΖΛϖΞϓϩͳͲͰղܾ͢Δ • ʮௐࠪʯͱʮ࣮ࢪʯͰϑΣʔζΛ෼͚Δ • εύΠΫ࡞ۀͷݟੵΓ͸೉͍͕͠ɺ࣮ࡍͷҠߦ࡞ۀ͸ݟੵΓ͕͠ ΍͍͢ • ʮ࣮ࢪʯظؒதʹɺผՕॴͷʮௐࠪʯΛฒߦͰ͖Δ

Slide 25

Slide 25 text

ࡉ͔ͳ Tipsʢ࣌ؒతʹׂѪʣ • ΞιγΤʔγϣϯʹ dependent: :destroy ͕͋Δ৔߹ɺಈ࡞͕มΘΔ • ϙϦϞʔϑΟοΫؔ࿈Ͱ͸ࢠϞσϧ΋࡟আ͞ΕΔ͕ɺதؒςʔϒϧؔ࿈Ͱ ͸ɺதؒཁૉϞσϧͷΈ࡟আ͞ΕΔ • callback ͳͲͰࢠϞσϧ΋࡟আ͢ΔΑ͏ʹ͢Δ • چˠ৽ͱ৽ˠچͷಉ࣌ॻ͖ࠐΈ͕྆ํଘࡏ͢ΔλΠϛϯά͕͋ΔͨΊɺೋॏʹ ൃՐ͢ΔͷΛճආ͢Δ • อଘ࣌ʹ :skip_double_write ͷΑ͏ͳ attribute Λੜ΍੍ͯ͠ޚ͢Δ • ൈ͚࿙Εݕ஌ͷϩά͸ಉ͡ՕॴͰଟྔʹग़ΔՄೳੑ͕͋ΔͨΊɺ1ϦΫΤετͰ ॏෳ͢ΔϩάΛ uniq ͢ΔػߏΛ࢓ࠐΉ

Slide 26

Slide 26 text

·ͱΊ • σʔλϞσϧઃܭΛஔ͖׵͑Δͷ͸݁ߏେม • ՄೳͳݶΓϦϦʔεલʹݕ౼͠Α͏…! • ͱ͸͍͑ɺ౰ॳ૝ఆͱมΘΔ͜ͱ͸͋ΓಘΔ • ෳࡶͰྑ͘ͳ͍෦෼͸ɺ์ஔ͍ͯ͠Δͱ૿͑Δ • ෳࡶͰ೉͍͔͠Βͦ͜ɺલྫΛ౿ऻͯ͠͠·͏ • ϦϑΝΫλϦϯάʹΑͬͯʮՁ஋Λఏڙ͠ଓ͚Δʯʹد༩͢Δ • ʮ͠ଓ͚ΔʯͨΊʹɺ෼͔Γ΍͘͢ɺखΛೖΕ΍͘͢อͭ