Slide 1

Slide 1 text

ϑϨʔϜϫʔΫΛ ࡞Βͳ͍ํ๏ )PX/05UPCVJMEGSBNFXPSLT 
 2019-06-21 ۜ࠲Rails#10 ॾڮګհ @moro

Slide 2

Slide 2 text

‣ ࣸਅ

Slide 3

Slide 3 text

Kyosuke MOROHASHI @moro

Slide 4

Slide 4 text

Slide 5

Slide 5 text

!5 SMS? What's SMSってなにをやってる会社なの?

Slide 6

Slide 6 text

https://twitter.com/sunaot/status/1002392476492038144

Slide 7

Slide 7 text

“ 情報インフラを構築することで、⾼齢社会を
 取り巻く⼈びと、⾼齢社会で働く⽅や事業者の⽅、 ⾼齢者ご⾃⾝やそのご家族などがイキイキと
 ⽣活できる社会の実現を⽬指しています。 — https://www.bm-sms.co.jp/philosophy/

Slide 8

Slide 8 text

!8 &

Slide 9

Slide 9 text

吳䒭⠓爡ؒأ ٥ ؒي ٥ ؒأ 匌❨鿪庥⼒蓎Ⱅ㕦⡝⿼♶⹛欵蓎Ⱅ㕦ةٙ٦ https://www.bm-sms.co.jp ؒٝآص،䱰欽؟؎ ز https://careers.bm-sms.co.jp/engineer/ join us!

Slide 10

Slide 10 text

͜Ε·Ͱͷ͋Β͢͡

Slide 11

Slide 11 text

Slide 12

Slide 12 text

Slide 13

Slide 13 text

‣ ͳͥϑϨʔϜϫʔΫʹ͠ͳ͍΄͏͕Α͍͔ ‣ ϑϨʔϜϫʔΫΛ࡞Βͳ͍ํ๏ ‣ ςϯϓϨʔτϝιουΛආ͚ͯ;ͭ͏ʹϝιουʹநग़͢Δ ‣ ςϯϓϨʔτϝιουΑΓ΋ετϥςδʔͰ֦ுͤ͞Δ ‣ lͪΐͬͱҧ͏ॲཧzΛදݱ͢ΔͨΊʹϒϩοΫΛड͚෇͚Δ ‣ ·ͱΊ੍ޚߏ଄Λ࢖͍खʹҕͶΔ

Slide 14

Slide 14 text

ͳͥ
 ϑϨʔϜϫʔΫʹ͠ͳ͍ ΄͏͕Α͍͔

Slide 15

Slide 15 text

ϥΠϒϥϦͱ ϑϨʔϜϫʔΫ

Slide 16

Slide 16 text

“ ͔͠͠ɺϥΠϒϥϦͰ͸ݺͼग़͠ଆ͕ϓϩάϥϜશ ମͷ੍ޚߏ଄ΛࢦఆͰ͖ͳ͍͕ɺϑϨʔϜϫʔΫͰ ͸ՄೳͰ͋Δɻ͜ͷ੍ޚͷ൓స͕ιϑτ΢ΣΞϑ ϨʔϜϫʔΫͷಛ௃Ͱ͋Δɻ https://ja.wikipedia.org/wiki/ιϑτ΢ΣΞϑϨʔϜϫʔΫ

Slide 17

Slide 17 text

‣ ʮར༻ऀ͕ݺͼग़͢ʯͷ͕ϥΠϒϥϦ ‣ ʮར༻ऀ ͷίʔυ Λݺͼग़͢ʯͷ͕ϑϨʔϜϫʔΫ ϑϨʔϜϫʔΫ͸੍ޚߏ଄Λࢦఆ͢Δ

Slide 18

Slide 18 text

‣ ͸͖ͬΓͱനࠇ͚ͭΒΕΔΘ͚Ͱ͸ͳ͍ɻ ‣ ར༻ऀͨΔΞϓϦ։ൃऀ͕ݺͼग़͢"DUJWF3FDPSE
 Ϟσϧʹఆٛͨ͠ίʔϧόοΫ͸"DUJWF3FDPSE͕ݺͼग़ͧ͢ʜ ‣ ར༻ऀ͕ॻ͘ίʔυͷ੍ޚߏ଄ΛͲΕ΄Ͳࢦఆ
 ͢Δ͔͠ͳ͍͔ɻ ˞۠ผ͸౓߹͍

Slide 19

Slide 19 text

‣ ϑϨʔϜϫʔΫ͸ɺͦͷ্Ͱͷ׆ಈΛ੍໿͢Δɻ ‣ ͍ΘΏΔʮϨʔϧ͔Β߱Γ͍ͨʯ໰୊ ‣ ඞͣ͠΋ѱ͍Θ͚Ͱ͸ͳ͍ʮ੍໿͕ࣗ༝Λ΋ͨΒ͢ʯ ‣ ʮͦͷ্Ͱͷ׆ಈʯ͸༧ଌͰ͖ͳ͍ɻ ‣ ͍͍ͨͯந৅Խ͕࿙ΕΔɻ ‣ ࡞ऀͷؾ࣋ͪΛߟ͑Α͏ͱͯ͠΋࡞ऀ΋ߟ͑ͯͳ͍͜ͱ΋ɻ ͳͥϑϨʔϜϫʔΫʹ͠ͳ͍΄͏͕ྑ͍͔

Slide 20

Slide 20 text

‣ ಡΈղ͘ͷʹϝλϓϩάϥϛϯάͷ஌͕ࣝඞཁʹͳΔ͜ͱଟ͍ɻ ‣ ϝλϓϩάϥϛϯάֶशۂઢ ίʔυࣗମ͕೉͘͠ͳΓ͕ͪ https://www.martinfowler.com/articles/rubyAtThoughtWorks.html

Slide 21

Slide 21 text

‣ ଟ͘ͷ"1*ͱͦͷ࢖͍ํΛֶश͢Δඞཁ͋Γɻ ‣ ࡞ऀͷؾ࣋ͪΛߟ͑ͯΞϓϦέʔγϣϯίʔυ Λॻ͘ɻ ϑϨʔϜϫʔΫࣗମ΋ֶशίετ͕͔͔Δ

Slide 22

Slide 22 text

‣ 3VCZͰ8FCΞϓϦ։ൃ͢Δͱ͖ͷυఆ൪ͱͯ͠
 ೥ϝΠϯετϦʔϜʹ͍Δɻ ‣ ৭Μͳ༻్ͷʮݸผࣄ৘ʯΛίϯτϦϏϡʔτ͞Ε ଓ͚͖ͯͨɻ ‣ ʮϨʔϧͷ߱ΓํʯͳΜͯͷ·ͰؚΊͯ๲େͳ
 ϊ΢ϋ΢͕஝ੵ͞Ε͍ͯΔɻ 3BJMT͸ϛϥΫϧ

Slide 23

Slide 23 text

‣ ࣗ෼ࣗ਎ΛؚΉ ະདྷͷϝϯςφʹର੍͠໿͠ͳ͍ɻ ‣ ະདྷʹͲ͏͍͏ιϑτ΢ΣΞʹ͍͔ͨ͠͸Θ͔Βͳ͍ɻ ‣ େମʹ͓͍ͯߟྀ͸ෆ଍͠ந৅Խ͸࿙ΕΔɻ ‣ ϥΠϒϥϦʹ͓ͯ͘͠ͱɺݺͿ΋ݺ͹ͳ͍΋ɺ
 ΋͏ݺ͹ͳ͘͢Δɺͷ΋ར༻ऀ͕ܾΊΒΕΔɻ ʮ;ͩΜ͸ʯϑϨʔϜϫʔΫʹ͢ΔͷΛආ͚Δ

Slide 24

Slide 24 text

ͱ͸͍͑ɺ ศརϝιουΛॻ͖ͨ͘ͳΔ͜ͱ͸ ͨ͘͞Μ͋ΔΘ͚Ͱ

Slide 25

Slide 25 text

‣ ͳͥϑϨʔϜϫʔΫʹ͠ͳ͍΄͏͕Α͍͔ ‣ ϑϨʔϜϫʔΫΛ࡞Βͳ͍ํ๏ ‣ ςϯϓϨʔτϝιουΛආ͚ͯ;ͭ͏ʹϝιουʹநग़͢Δ ‣ ςϯϓϨʔτϝιουΑΓ΋ετϥςδʔͰ֦ுͤ͞Δ ‣ lͪΐͬͱҧ͏ॲཧzΛදݱ͢ΔͨΊʹϒϩοΫΛड͚෇͚Δ ‣ ·ͱΊ੍ޚߏ଄Λ࢖͍खʹҕͶΔ

Slide 26

Slide 26 text

ϑϨʔϜϫʔΫΛ ࡞Βͳ͍ํ๏

Slide 27

Slide 27 text

ݴ͍׵͑Δͱ ੍ޚߏ଄Λ
 ࢖͍खʹҕͶΔํ๏

Slide 28

Slide 28 text

ςϯϓϨʔτϝιουΛආ͚ͯ ;ͭ͏ʹϝιουʹநग़͢Δ

Slide 29

Slide 29 text

‣ ΦʔόʔϥΠυ͞ΕͯΔϝιουΛ࢓૊Έଆ͕ݺͿɻ ݺ͹ΕΔଆ͔Βߏ଄͕ݟ͑ͳ͍ɻ ‣ 34QFDͷMFUTVCKFDU໰୊΋ಉࠜͰ͋Δͱ΋ݴ͑Δɻ ‣ ۩৅ςετέʔε͔Β཭ΕͨʮϑΝΠϧͷ্ͷํʯʹ
 ߏ଄͕Ͱ͖ΔͷͰɺݟ͑ͳ͍͠ɺม͑ͮΒ͍ɻ ςϯϓϨʔτϝιουύλʔϯͷ໰୊

Slide 30

Slide 30 text

‣ ܧঝͯ͠͠·͏ͷͰɺϑϨʔϜϫʔΫͷ಺෦ߏ଄Λ ࡽͯ͠͠·͏ɻ ‣ ͞ΘΓͨ͘ͳΔΑͶ ‣ ͦͯ͠όʔδϣϯΞοϓͰ͖ͳ͘ͳΔ ‣ 3BJMTΞϓϦ͋Δ͋Δɻ ςϯϓϨʔτϝιουύλʔϯͷ໰୊

Slide 31

Slide 31 text

‣ 3BJMTࣗମ͕ϥΠϒϥϦఏڙΫϥεΛܧঝͯ͠࢖͏
 ϑϨʔϜϫʔΫͳͷͰɺࣗ෼Ͱ΋ͦ͏ॻ͖ͨ͘ͳΔɻ ‣ ʜΑͶ ‣ 999#BTF͍ͬͯ͏ந৅ΫϥεΛఆٛͨ͜͠ͱ͋Δਓ ‣ 3BJMT͔ͩΒͰ͖Δ͜ͱɻ 3BJMT͸ϛϥΫϧ

Slide 32

Slide 32 text

ϝιουʹநग़͠ɺࣗ෼Ͱݺͼग़͢

Slide 33

Slide 33 text

‣ Ұ࿈ͷΦϒδΣΫτάϥϑΛ࡞Δϝιο υʹநग़͠ɺ࡞Γ͍ͨଆ͕ݺͼग़͢ɻ ‣ ࠩ෼ΛҾ਺Ͱ༩͑ͭͭɺ ‣ ΊͬͪΌී௨ͷ͜ͱΛݴͬͯ·͢ ϝιουʹநग़͠ɺࣗ෼Ͱݺͼग़͢

Slide 34

Slide 34 text

let!(:article) { create(:article, author: author } # ...͜ͷؒ 30ߦ... context ';ͭ͏ͷϢʔβʔͷهࣄ͸Ұཡදࣔର৅' do let(:author) { create(:author) } it { expect(Article.indexable).to include(article) } context 'ୀձͨ͠Ϣʔβʔͷهࣄ͸Ұཡදࣔର৅֎' do let(:author) { create(:author, retired_at: Time.now) } it { expect(Article.indexable).not_to include(article) }

Slide 35

Slide 35 text

def article_by(user) create(:article, author: author) end context ';ͭ͏ͷϢʔβʔ' do let(:article) { article_by(create(:user)) } it { expect(Article.indexable).to include(article) } context 'ୀձͨ͠Ϣʔβʔ' do let(:article) { article_by(:author, retired_at: Time.now) } it { expect(Article.indexable).not_to include(article) }

Slide 36

Slide 36 text

‣ BVUIPSVTFS͕Ͳ͏࡞ΒΕͲ͏࢖ΘΕΔ͔ɺॱΛ௥ͬ ͯಡΊΔɻ ‣ ϔϧύʔϝιου͕େ͖͘ͳΔଟ͘ͳΓ͗͢Δ
 ଞͷϑΝΠϧ͔Β΋࢖͍͍ͨ৔߹͸ɺී௨ʹ
 ίʔυΛ෼ׂ͢ΔͱΑ͍ɻ ‣ কདྷɺςετίʔυΛॻ͘ਓ͕ɺ࢖͍ํΛࣗ෼Ͱ
 ܾΊΒΕΔɻ

Slide 37

Slide 37 text

ҧ͏ॲཧΛڬΈࠐΉͨΊʹ ετϥςδʔύλʔϯΛ࢖͏

Slide 38

Slide 38 text

‣ ڞ௨ͷલॲཧΛͯ͠ɺຊॲཧͯ͠ɺڞ௨ͷޙॲཧ͕
 ͋Δ৔߹ͳͲɻ ‣ ͞Βʹຊॲཧͷྫ֎ॲཧ΋ඞཁͳ৔߹ͳΜ͔͸৑௕ʹͳΓ͕ͪɻ ‣ ͜ͷຊॲཧ͚ͩΛม͍͑ͨɻ ‣ ςϯϓϨʔτϝιου࢖͍ͨ͘ͳΓ͕ͪɻ ϝιουͷҰ෦͚ͩม͍͑ͨ৔߹͕͋Δ

Slide 39

Slide 39 text

class TwitterNotification < BaseNotification private def before_request authorize(@article.author) def request @user = article.author.access_token ... def after_request nil class BaseNotification def notify(article) @article = article before_request request after_request private def request raise NotImplementedError

Slide 40

Slide 40 text

ετϥςδʔύλʔϯΛ࢖͏

Slide 41

Slide 41 text

‣ Ұ෦͚ͩม͍͑ͨॲཧΛɺετϥς δʔΦϒδΣΫτͷ஫ೖͰදݱ͢Δɻ ετϥςδʔύλʔϯΛ࢖͏

Slide 42

Slide 42 text

class TwitterNotification < BaseNotification private def before_request authorize(@article.author) def request @user = article.author.access_token ... def after_request nil class BaseNotification def notify(article) @article = article before_request request after_request private def request raise NotImplementedError

Slide 43

Slide 43 text

class SnsNotification def notify(article) #=> [TwitterNotification.new, FacebookNotofication.new...] SnsNotification.targets.each do |sns| sns.notify(article)

Slide 44

Slide 44 text

‣ ݺͼग़͢γʔέϯε͕ࣗ໌ʹͳΔɻ ‣ ݺ͹ΕΔݸʑͷετϥςδʔଆ΋ΠϯλʔϑΣʔε ͕͸͖ͬΓ͢Δɻ ‣ ৼΔ෣͍ʹӨڹΛ༩͑Δύϥϝʔλ͕໌֬ʹͳΔͷͰɺςετ΋͠΍͍͢ ‣ ݺͼग़͠ݩείʔϓʹΞΫηεͰ͖ͳ͍ ‣ CJOEJOH@PG@DBMMFSͷ͜ͱ͸๨ΕΑ͏

Slide 45

Slide 45 text

lͪΐͬͱҧ͏ॲཧzΛ
 ϒϩοΫͱͯ͠ड͚औΔ

Slide 46

Slide 46 text

“ EPFOE·ͨ͸\^Ͱғ·Εͨίʔυͷஅย ϒ ϩοΫͱݺ͹ΕΔ ΛޙΖʹ෇͚ͯϝιουΛݺͼग़ ͢ͱɺͦͷϝιουͷ಺෦͔ΒϒϩοΫΛධՁͰ͖ ·͢ɻ
 ϒϩοΫ෇͖ϝιουΛࣗ෼Ͱఆٛ͢Δʹ͸ZJFME ࣜΛ࢖͍·͢ɻ

Slide 47

Slide 47 text

‣ ॲཧΛΦϒδΣΫτͱͯ͠ந৅Խͨ͠΋ͷɻ ‣ 3VCZͷಛ௃ਓؾϙΠϯτͷͭ ‣ ͍ΘΏΔʮߴ֊ؔ਺ʯ ‣ DBMMͰॲཧΛݺͼग़͢ɻ ϒϩοΫ

Slide 48

Slide 48 text

‣ ;ͭ͏ͷ܁Γฦ͠ ‣ .PEFMBMMFBDIEPFOE ‣ ॲཧͷڥք ‣ .PEFMUBOTBDUJPOEPFOE ‣ %4- ‣ 3BJMTBQQMJDBUJPOSPVUFTESBXEPFOE ‣ 34QFDͷMFU 3BJMTΞϓϦʹ͓͚ΔϒϩοΫ

Slide 49

Slide 49 text

‣ ϥΠϒϥϦ੍͕ޚߏ଄Λࢦఆ͍ͯ͠Δ ‣ ݺͼग़͠ଆͷ۩ମతͳॲཧࣗମΛϒϩοΫͱͯ͠ड͚ɺ
 ϥΠϒϥϦϑϨʔϜϫʔΫͰ४උ্ͨ͠Ͱݺͼग़͢ɻ ‣ Ͱ΋ɺऔΒΕͨؾ͕͠ͳ͍ ‣ FBDI΍USBOTBDUJPO͸ී௨ʹಡΊΔ ϒϩοΫΛΑ͘ݟͯΈΔͱ

Slide 50

Slide 50 text

model.transaction do model1.save! model2.save! end ྫ

Slide 51

Slide 51 text

module Transactionable def transaction do_begin do_something do_commit rescue do_rollback class Model include Transactionable private def do_something model1.save! model2.save! NJYJOͰॻ͍ͯΈΔ

Slide 52

Slide 52 text

class MyModel < AbstractModel private def do_something model1.save! model2.save! ςϯϓϨʔτϝιουͰॻ͍ͯΈΔ class AbstractModel def transaction do_begin do_something do_commit rescue do_rollback private def do_something raise NotImplementedError

Slide 53

Slide 53 text

class SaveStrategy def initialize(*models) def do_something @models.each(&:save!) ... s = SaveStrategy.new( model1, model2 ) model.transaction(s) ετϥςδʔͰॻ͍ͯΈΔ class Model def transaction(strategy) do_begin strategy.do_something do_commit rescue do_rollback

Slide 54

Slide 54 text

class Model def transaction(&strategy) do_begin strategy.call # or yield do_commit rescue do_rollback ϒϩοΫΛड͚෇͚Δ model.transaction do model1.save! model2.save!

Slide 55

Slide 55 text

‣ DBMMΛڞ௨ΠϯλʔϑΣʔεͱͨ͠ετϥςδʔͱ ΋ݴ͑Δɻ ‣ ͍ΘΏΔDBMMBCMFPCKFDU ‣ ϒϩοΫΛ࢖͏ͱɺΞϓϦέʔγϣϯίʔυͷಡΈ खͷίϯςΩετ͕ܧଓ͢Δɻ ‣ CJOEJOHQSZΛೖΕΔͱ͜Ζ͕ࣗ໌ ϒϩοΫͱετϥςδʔ

Slide 56

Slide 56 text

class MyModel < AbstractModel private def do_something model1.save! model2.save! ྫEP@TPNFUIJOH͕ݺ͹Εͯͳͦ͞͏ͳͱ͖Ͳ͏͢Δ class AbstractModel def transaction do_begin do_something do_commit rescue do_rollback private def do_something raise NotImplementedError

Slide 57

Slide 57 text

‣ ϒϩοΫΛड͚෇͚Δͱɺʮͪΐͬͱҧ͏ॲཧ Λࠩ͠ࠐ·͍ͤͨʯͱ͖ʹͷ੍ޚߏ଄Λݺͼग़ ͠ଆʹҕͶ͍ͯΔΑ͏ʹݟͤΒΕΔɻ ‣ ͦ͏͍͏ؾ࣋ͪͰ࢖͑Δͷ͕େࣄɻ ‣ 3VCZͬΆ͍ίʔυʹ΋ͳΔɻ

Slide 58

Slide 58 text

‣ ͳͥϑϨʔϜϫʔΫʹ͠ͳ͍΄͏͕Α͍͔ ‣ ϑϨʔϜϫʔΫΛ࡞Βͳ͍ํ๏ ‣ ςϯϓϨʔτϝιουΛආ͚ͯ;ͭ͏ʹϝιουʹநग़͢Δ ‣ ςϯϓϨʔτϝιουΑΓ΋ετϥςδʔͰ֦ுͤ͞Δ ‣ lͪΐͬͱҧ͏ॲཧzΛදݱ͢ΔͨΊʹϒϩοΫΛड͚෇͚Δ ‣ ·ͱΊ੍ޚߏ଄Λ࢖͍खʹҕͶΔ

Slide 59

Slide 59 text

·ͱΊ
 ੍ޚߏ଄Λ
 ࢖͍खʹҕͶΔ

Slide 60

Slide 60 text

‣ ศརϥΠϒϥϦ͕ศརͳͷ͸ؒҧ͍ͳ͍ɻ ‣ ੍ޚߏ଄Λͯ͠͠ͳͯ͘΋ɺศརϝιουΛఏڙ͢Δͷ͕े෼ศར ‣ ʮͪΐͬͱҧ͏ॲཧʯ͸ετϥςδʔͰදݱ͢Δɻ ‣ ܧঝͤͯ͞ݺͼग़͢ॲཧ͚ͩΛॻ͔ͤͳ͍ ‣ ϒϩοΫ͍͍Ϡπɻੵۃతʹ׆༻͠·͠ΐ͏ɻ ‣ 3VCZ͍͍ΑͶ ϥΠϒϥϦίʔυͱΞϓϦίʔυΛૄʹอͭ

Slide 61

Slide 61 text

‣ ϔϧύʔϝιουΛɺετϥςδʔύλʔϯΛɺϒϩοΫΛ ࢖͑͹Α͍Θ͚Ͱ͸ͳ͍ɻ ‣ 'PP'SBNFXPSLOBOUPLB@QSPD DPOUFYU \^Έ͍ͨͳ ‣ ͍ͭɺͲ͏ݺ͹ΕΔͷ ‣ ʮࠓ͜ͷศརϥΠϒϥϦΛॻ͍ͯΔࣗ෼͸ɺͦΕ͕
 Ͳ͏࢖ΘΕΔ͔·ͩ஌Βͳ͍ʯͱ͍͏ؾ࣋ͪʹ޲͖߹͏ɻ )PXʹ͍ͭͯ࿩͠·͕ͨ͠

Slide 62

Slide 62 text

‣ ·ͩݟ͵ΞϓϦέʔγϣϯίʔυʹɺඞཁҎ্ͷ
 ੍໿Λ՝͞ͳ͍Α͏ʹ͢Δɻ ‣ ΞϓϦέʔγϣϯͰԿΛ͍͔ͨ͠͸ɺͦͷͱ͖ʹͳΒͳ͍ͱΘ͔Βͳ͍ɻ ‣ ͦͷ࣌ɺͦͷਓୡ͕ɺ޲͖߹͑Δ༨஍Λ࢒͢ɻ ‣ ۩ମతͳ໰୊ʹ޲͖߹͍ͬͯΔਓΛϦεϖΫτɻະདྷͷࣗ෼͔΋ ੍ޚߏ଄Λ࢖͍खʹҕͶΔ