Slide 1

Slide 1 text

ϑΥʔϜΦϒδΣΫτͱͷ
 ޲͖߹͍ํ 2018-07-11 Rails Developers Meetup 2018 Day 3 Extreme
 ॾڮګհ @moro

Slide 2

Slide 2 text

‣ (ࣸਅ) Title

Slide 3

Slide 3 text

Kyosuke MOROHASHI moro moro

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

גࣜձࣾΤεɾΤϜɾΤε ೥૑ۀɺ೥౦ূҰ෦্৔ɻ ߴྸࣾձΛհޢɾҩྍɾΩϟϦΞɾϔϧεέΞɾ γχΞϥΠϑͱଊ͑ɺߴྸࣾձʹదͨ͠৘ใαʔ ϏεΛଟ਺։ൃɾӡӦ

Slide 6

Slide 6 text

https://www.wantedly.com/companies/sms

Slide 7

Slide 7 text

͖ΐ͏ͷ࿩

Slide 8

Slide 8 text

‣ “RailsͷΩϨΠͳઃܭ"࠷ॳ͔Β͢΂ͯઃܭ͢Δͷ
 Ή͔͍ͣ͠ͷͰ൓෮ͯ͠࡞ΔͱΑͦ͞͏ɻ ‣ ʰॅΈͳ͕Β૿ங͍ͯ͘͠ײ͡ʱ@m_seki
 https://speakerdeck.com/m_seki/re-iterative-development-iteration-4?slide=57 ‣ Railsʹ͓͍ͯ͸ɺͦͷͱ͔͔ͬΓͱͯ͠ϑΥʔϜʹ
 ண໨͢Δͷ͸ѱ͘ͳͦ͞͏ɻ ͖ΐ͏ͷ࿩

Slide 9

Slide 9 text

എܠ

Slide 10

Slide 10 text

‣ DBͷςʔϒϧʹ΄΅Ұகͨ͠ߏ଄ͷσʔλ͕POST͞Εͯ ͖ͯɺͦΕΛARͰγϯϓϧʹӬଓԽ͢Δɻ ‣ ͳ͔ͳ͔ͦ͏΋ߦ͔ͳ͍͜ͱ΋ଟ͍ΑͶɻ ૉ๿ͳRails͕૝ఆ͍ͯ͠Δ͜ͱ

Slide 11

Slide 11 text

‣ Ϣʔβʔ͕໨ʹ͢Δ৘ใ୯Ґ(≒ϑΥʔϜͷߏ੒)ͱɺਖ਼نԽ ͞Εͨσʔλߏ଄͸ҟͳΔɻ ‣ DBʹӬଓԽ͢Δ͚ͩͰ͸ࡁ·ͳ͍͜ͱ͕͋Δɻ ‣ ϝʔϧΛૹΔɺϩάΛऔΔɺඇಉظδϣϒΛΩοΫ͢Δɺ Πϕϯτͱͯ͠Publish͢ΔɺɺɺͳͲͳͲ “ͦ͏΋ߦ͔ͳ͍͜ͱ”

Slide 12

Slide 12 text

ࠩҟΛຒΊΔςΫχοΫ ͏·͘ߦ͖ͦ͏͚ͩͲͬ͘͠Γ͜ͳ͍΍ͭ

Slide 13

Slide 13 text

‣ ίϯτϩʔϥʔͰARϞσϧʹ٧Ί௚͢ɻ ‣ ͍ΘΏΔFat ControllerʹͳΓ͕ͪ ‣ ͷͰϞσϧʹدͤΔɺͱFat Model ‣ ·͍͍͋ͯ͑͠͹Ϟσϧ͕Ͱ͔͍΄͏͕·ͩϚγ… ࠩҟΛຒΊΔςΫχοΫ

Slide 14

Slide 14 text

‣ accept_nested_attributes ͰҰ࿈ͷσʔλΛ
 ·ͱΊͯೖྗͤ͞Δ ‣ ϑΥʔϜ΍ίϯτϩʔϥʹɺӬଓԽ૚ͷσʔλάϥϑ͕࿐ग़͢Δ ‣ ͓͢͢Ί͠·ͤΜɻ ࠩҟΛຒΊΔςΫχοΫ

Slide 15

Slide 15 text

‣ ʮӬଓԽ͢Δ͚ͩʯͰͳ͍ॲཧΛίʔϧόοΫͱ࣮ͯ͠ݱ ͢Δɻ ‣ ίϧόοΫ͍ͨ͠ͱ͖ͱɺ୯ʹσʔλΛอଘ͍ͨ͠ͱ͖ͷหผ͕͍ͨ΁Μ ‣ ίʔϧόοΫʹͨ͘͞Μͷ if ͕Ͱ͖ͯ͘Δͷ͕༧ஹ ࠩҟΛຒΊΔςΫχοΫ

Slide 16

Slide 16 text

‣ 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 ͍ͨ΁ΜͩΑͶɺɺɺͱ͍͏ͷ͕஌ΒΕ͖ͯͨ

Slide 17

Slide 17 text

͸͡Ί͔Β ͪΌΜͱ ઃܭ͢Δͷ͸Ή͔͍ͣ͠

Slide 18

Slide 18 text

ܧଓతʹҭͯΔҰา໨

Slide 19

Slide 19 text

Slide 20

Slide 20 text

“ ࠷΋༗༻ͳઃܭݪଇʹɺϓϩάϥϜʢϢʔ βʔΠϯλʔϑΣΠεʣͷϓϨθϯςʔγϣ ϯ૚ͱͦͷଞͷػೳΛ͏·͘෼͚Δɺͱ͍ ͏ͷ͕͋Γ·͢ɻ ϓϨθϯςʔγϣϯͱυϝΠϯͷ෼཭ http://bliki-ja.github.io/PresentationDomainSeparation/

Slide 21

Slide 21 text

‣ Webͷೖྗ = request ʹू໿͞Ε͍ͯΔσʔλ ‣ ͱͦΕΛಋͨ͘ΊͷϑΥʔϜ΍ͦͷଞը໘ ‣ϦϯΫͰͷGETભҠ΋ೖྗͱ͍͑͹ೖྗ͚ͩͲɺ
 ͜͜Ͱ͸;Ε·ͤΜɻ ‣ඇಉظδϣϒͰ͸ AJ#perform ͷҾ਺΍؀ڥม਺ͳͲ͕
 ೖྗͱͳΔɻ RailsͷϓϨθϯςʔγϣϯ

Slide 22

Slide 22 text

‣ ʮͦͷଞͷػೳʯ ‣ 1ͭҎ্ͷςʔϒϧʹҰ࿈ͷσʔλΛ·ͱΊͯӬଓԽ͢Δ ‣ ࿈ܞγεςϜʹ޲͚ͯΠϕϯτΛPub͢Δ ‣ ͳͲͳͲ RailsͰ͍͏υϝΠϯ

Slide 23

Slide 23 text

‣ ϓϨθϯςʔγϣϯͷ஌͕ࣝɺʮͦͷଞͷػೳʯʹϦʔΫ ͠ͳ͍Α͏ʹɻ·ͣ͸ೖྗΛ͸͖ͬΓͤ͞Δɻ ʮ͏·͘ʯ෼͚Δ

Slide 24

Slide 24 text

‣ ίϯτϩʔϥʹͯparams͔Β஋ΛऔΓग़͠ɺHash΍
 จࣈྻͱͯ͠ѻ͏ɻ ‣ ࣮ଶ͕ AC::Parameters Ͱ΋ Hash ͷΑ͏ʹѻ͏ɻ৺ͷ໨ͰܕΛݟΔ ‣ HTTP༝དྷͷσʔλ΋ɺrequest͔ΒऔΓग़͓ͯ͘͠ɻ ‣ #user_agent ͱ͔ɺΫοΩʔͷ஋ͱ͔΋ ೖྗΛ͸͖ͬΓ

Slide 25

Slide 25 text

‣ ొ࿥ϖʔδͰϝʔϧΞυϨεΛೖྗͤ͞Δɻ ‣ ೖྗ͞ΕͨϝʔϧΞυϨεΛอଘ͢Δ ྫ: Ϣʔβʔొ࿥

Slide 26

Slide 26 text

‣ ࣮ࡏ֬ೝ༻ͷURLτʔΫϯ΋Ұॹʹอଘ͢Δɻ ‣ ͜Ε͸ after create ίʔϧόοΫͰ΍Δ͜ͱ΋ଟ͍͠ɺͦΕ͚ͩͳΒ͞΄ͲࠔΒͳ͍͚Ͳ΋ɻ ‣ τʔΫϯΛؚΉURLΛϝʔϧͰૹ৴͢Δɻ ‣ ͜ΕΛίʔϧόοΫͰ΍ΔͱՒࠜʹͳΓ͕ͪɻ ྫ: AR͚ͩͰ·͔ͳ͍ͮΒ͍ʮ΍Δ͜ͱʯ

Slide 27

Slide 27 text

‣ ίϯτϩʔϥͰऔΓग़ͨ͠஋ͨͪΛೖྗʹ͢Δɻ ‣ ୯Ұͷϝιουݺͼग़͠ͰॲཧҰࣜΛ࣮ߦ͢Δɻ ‣ ໊લΛ͚ͭΔͷ͸૬มΘΒͣ೉͍͠ ‣ ಈ໊ࢺʹͨ͠Γɺpre/suffix͚ͭͨΓɺͦͷଞن໿Λಋೖͨ͠Γɻɻɻ ‣ ؤுΕ͹ม͑ΒΕΔͷͰɺνʔϜͰͬ͘͠ΓདྷΔ΍ͭʹ͢ΔͱΑ͍ɻ ෼͚ΔͨΊͷ૚Λಋೖ͢Δ(ศ্ٓϑΥʔϜΦϒδΣΫτͱݺͼ·͢)

Slide 28

Slide 28 text

“ • ಉ͡جຊϓϩάϥϜΛɺॏෳίʔυͳ͠ʹɺෳ਺ͷϓϨθϯςʔγϣϯʹ ରԠͤ͞Δ͜ͱ͕Ͱ͖Δ • ϢʔβʔΠϯλʔϑΣΠε͸ςετ͕͠ʹ͍ͨ͘ΊɺͦΕΛ෼཭͢Δ͜ͱ ʹΑΓɺςετՄೳͳϩδοΫ෦෼ʹूதͰ͖Δ • εΫϦϓτ༻ͷ"1*΍αʔϏεͱͯ͠֎෦Խ͢ΔͨΊͷ"1*Λָʹ௥ՃͰ ͖Δʢબ୒ՄೳͳϓϨθϯςʔγϣϯ෦෼Ͱݟ͔͚Δʣ ϓϨθϯςʔγϣϯͱυϝΠϯͷ෼཭ http://bliki-ja.github.io/PresentationDomainSeparation/

Slide 29

Slide 29 text

‣ ͜ͷ”෼͚ΔͨΊͷ૚”΁ͷೖྗ͸POROʹͳΔͷͰɺςε τ͔Β؆୯ʹݺͼग़ͤΔɻ ‣ PORO: Plain Old Ruby Object = ී௨ͷΦϒδΣΫτ ‣ ؆୯ʹݺͼग़ͤΔͷͰɺଞͷςετͰͷσʔληοτΞο ϓʹ΋࢖͑Δɻ ςετՄೳ

Slide 30

Slide 30 text

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Λϝʔϧ͢Δͷͷςετ

Slide 31

Slide 31 text

͜ͷʮϑΥʔϜΦϒδΣΫτʯΛߋʹɺͨͱ͑͹͜Μͳ;͏ʹҭͯͨ͘ͳͬͨͱͯ͠: 1. ϑΥʔϜΦϒδΣΫτ͸ೖྗϋϯυϦϯάʹͱͲΊɺ
 ӬଓԽͷͨΊʹαʔϏε૚Λ΋͏Ұ૚ઃ͚͍ͨɻ 2. ϝʔϧૹ৴͸ΤϯςΟςΟӬଓԽΛPub/SubͰݕ஌ͯ͠
 ૄ݁߹ʹ͍ͨ͠ɻ “ϩδοΫ෦෼ʹूதͰ͖Δ”

Slide 32

Slide 32 text

> ӬଓԽͷͨΊʹαʔϏε૚Λઃ͚͍ͨ 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ϨΠϠઃ͚ͯ΋ɺϓϨθϯςʔγϣϯͱͷΠϯ λʔϑΣʔε͸มΘΒͣ҆ఆ͍ͯ͠Δɻ

Slide 33

Slide 33 text

> Pub/SubͰૄ݁߹ʙ UserRegistrationForm.new(email: email).call + OurJob.execute_all! token = extract_token_from_sent_email(AM::Base.deliveries.last) ‣ ΠϯλʔϑΣʔε͸҆ఆͨ͠··ɺΞʔΩςΫνϟมߋʹ ඞཁͳमਖ਼͚ͩΛೖΕΕ͹Α͍ɻ

Slide 34

Slide 34 text

‣ ΠϯλʔϑΣʔε͕҆ఆ͢ΔͷͰɺϩδοΫ෦෼Λ
 มԽ/ચ࿅͢Δࣗ༝౓͕ಘΒΕΔɻ ‣ (ಈ࡞͢Δ && !ΩϨΠ) ͳίʔυΛɺ
 (ಈ࡞͢Δ && ΩϨΠ) ͳίʔυʹҭͯΒΕΔɻ ‣ ϦϑΝΫλϦϯά! “ϩδοΫ෦෼ʹूதͰ͖Δ”

Slide 35

Slide 35 text

ศ্ٓϑΥʔϜΦϒδΣΫτͱݺΜͩ ҙਤ

Slide 36

Slide 36 text

‣ A: ͲͬͪͰ΋͍͍ ‣ ࣗಈςετ͕͋ͬͯϦϑΝΫλϦϯά͠΍͘͢ͳ͍ͬͯΕ͹okɻ ‣ ʮೖྗ஋ΛͱΓ·ͱΊͯόϦσʔγϣϯ·ͰΛ͢Δ૚ʯͱɺ
 ʮͦͷvalidͳೖྗ஋ͰॲཧΛ͢Δ૚ʯʹ෼ׂͯ͠΋͍͍Μ͡Όͳ͍͔ͳɻ ‣ ࠷ॳʹখ͘͞࡞Δͱ͖UIͱ͚ۙͮͨ΄͏͕͍͍Μ͡Όͳ͍͔ͳ ‣ ʮϑΥʔϜʯͬͯͭ·ΓɺαʔϏεΛఏڙ͢Δଆ͕ར༻ऀʹظ଴͢Δ
 ߦಈͦͷ΋ͷͩΑͶɻ ‣ ͦ͜ʹԊͬͨ΋ͷΛ࡞Δͷ͕ૉ௚͡Όͳ͍͔ͳɻ αʔϏεϨΠϠ͡Όͳͯ͘ϑΥʔϜΦϒδΣΫτਪ͠ͳͷ͸ͳͥ?

Slide 37

Slide 37 text

‣ ʮೖྗʯͱʮϩδοΫ෦෼ʯΛ෼͚Α͏ ‣ ϓϩμΫτίʔυ΋ςετ΋εοΩϦ͢Δ͸ͣ! ‣ ࠷ॳ͸খ͘͞φΠʔϒʹ࡞Ζ͏ ‣ ઃܭ͕Μ͹Γ͗ͯ͢ർΕͳ͍Α͏ʹ… ‣ Ͳ͏͍͏ந৅Խ͕ྑ͍ͷ͔ɺ࠷ॳΘ͔Βͳ͍͔ΒͶ ‣ ͪΌΜͱ೔ʑϦϑΝΫλϦϯά͠Α͏ ‣ φΠʔϒͳ··ΰνϟοͱੵΈଓ͚ΔͱͦΕ͸μϝͰ͢Ͷ ͲͬͪͰ΋Α͘ͳ͍͜ͱ

Slide 38

Slide 38 text

·ͱΊ

Slide 39

Slide 39 text

‣ Ϗϡʔ / ίϯτϩʔϥ / AR::B ͷࡾ૬ߏ଄Ͱ·͔ͳ͑ͳͦ͏ ͳ৔߹ɺബ͍૚Λ΋͏Ұ૚࡞ͬͯΈΔͱΑ͍ɻ ‣ ίϯτϩʔϥ͕ѻ͏Webͷೖྗ஋ͱɺϩδοΫʹඞཁͳ
 ೖྗ஋ͷڥքͱͳΔ͜ͱΛҙࣝ͢Δɻ ‣ φΠʔϒ͔ͭςετ͕ॻ͖΍͍͢ϨΠϠ͔Β͸͡Ίͯɺ
 ൓෮͠ͳ͕ΒมԽ͍͚ͯ͠ΔΑ͏ʹ! ·ͱΊ