Slide 1

Slide 1 text

Web & Rails 2017-08-08 @moro ॾڮګհ

Slide 2

Slide 2 text

ࢀߟ৘ใ: ͖ΐ͏͸ྔ͕ଟ͍ͷͰ
 ͋ͱ͔ΒৼΓฦΔͨΊͷࢿྉ

Slide 3

Slide 3 text

https://railstutorial.jp/

Slide 4

Slide 4 text

https://www.railstutorial.org/ ':*ӳޠͷݪஶ΋͋ΔΑ

Slide 5

Slide 5 text

Slide 6

Slide 6 text

':*ͪ͜Β΋ӳޠ൛͋Γ·͢ɻ։ൃ൛ FEHF ͷΨΠυ΋͋Δɻ

Slide 7

Slide 7 text

‣ RailsΛ࢖ͬͯ؆୯ͳWebΞϓϦέʔγϣϯΛ࡞Δɻ ‣ ͦΕΛ௨ͯ͡ɺWebΞϓϦέʔγϣϯʹඞཁͳཁૉ ٕज़ʹ;ΕΔɻ ‣ REST: αʔϏεͷཁૉΛʮϦιʔεͷಡΈॻ͖ʯͱந৅ԽͰ͖Δ ‣ DBઃܭ: ਖ਼نԽͨ͠σʔλΛARܦ༝Ͱ͞ΘΔ ‣ ηογϣϯ: HTTPͰΫϥΠΞϯτঢ়ଶΛѻ͏ఆ൪Λ஌Δ ࠓ೔ͷΰʔϧ

Slide 8

Slide 8 text

ͳ͍ͥ·Web͔

Slide 9

Slide 9 text

‣ εϚϗΞϓϦΛ௨ͯ͡Ձ஋Λಧ͚ΔͨΊͷʮ;ͭ͏ʯͷ
 ܦ࿏ͱͯ͠ɺJSON over HTTPͳAPI͕͋Δɻ ‣ ػցֶशetc… ͷ੒ՌΛϢʔβʹಧ͚Δ৔߹ʹ΋
 Webٕज़Λհ͢Δ͜ͱ͕ଟ͍ɻ ‣ Webͦͷ΋ͷ΋·ͩ·ͩ໘ന͍ (ࢲ͸ίί) ‣ ϏδωεϩδοΫΛॻ͖΍͍͢͠Ͷɻ ͳ͍ͥ·8FC͔

Slide 10

Slide 10 text

Railsͱ͸

Slide 11

Slide 11 text

‣ Railsͱ͸ɺRubyϓϩάϥϛϯάݴޠͰॻ͔ΕͨWebΞϓϦ έʔγϣϯϑϨʔϜϫʔΫͰ͢ɻRails͸ɺ͋ΒΏΔ։ൃऀ ͕WebΞϓϦέʔγϣϯͷ։ൃΛ࢝ΊΔ͏͑ͰඞཁͱͳΔ ࡞ۀ΍ϦιʔεΛࣄલʹԾఆͯ͠४උ͓ͯ͘͜͠ͱͰɺ WebΞϓϦέʔγϣϯΛΑΓ؆୯ʹϓϩάϥϛϯάͰ͖Δ Α͏ʹઃܭ͞Ε͍ͯ·͢ɻ ‣ -- http://railsguides.jp/getting_started.html

Slide 12

Slide 12 text

‣ Railsͱ͸ɺRubyϓϩάϥϛϯάݴޠͰॻ͔ΕͨWebΞϓϦ έʔγϣϯϑϨʔϜϫʔΫͰ͢ɻRails͸ɺ͋ΒΏΔ։ൃऀ ͕WebΞϓϦέʔγϣϯͷ։ൃΛ࢝ΊΔ͏͑ͰඞཁͱͳΔ ࡞ۀ΍ϦιʔεΛࣄલʹԾఆͯ͠४උ͓ͯ͘͜͠ͱͰɺ WebΞϓϦέʔγϣϯΛΑΓ؆୯ʹϓϩάϥϛϯάͰ͖Δ Α͏ʹઃܭ͞Ε͍ͯ·͢ɻ ‣ -- http://railsguides.jp/getting_started.html

Slide 13

Slide 13 text

WebΞϓϦέʔγϣϯͱ HTTP

Slide 14

Slide 14 text

‣ Hypertext Transfer Protocol ‣ ෼ࢄίϯϐϡʔλؒͰHTMLͳͲͷ৘ใΛ΍ΓͱΓ͢ΔͨΊͷϓϩτίϧɻ ‣ ΫϥΠΞϯτ(ϒϥ΢βɺεϚϗΞϓϦɺผͷαʔόΞϓϦͳͲ)͕ɺ αʔό্ͷʮԿ͔ͷ৘ใʯΛʮͲ͏ͯ͠΄͍͠ʯͱ ཁٻ(ϦΫΤετ)͠ɺαʔό͕Ԡ౴(Ϩεϙϯε)͢ Δɻ )551

Slide 15

Slide 15 text

‣ Կ͔ͷ৘ใ: ύεͱΫΤϦ ‣ Ͳ͏ͯ͠΄͍͠: HTTPϝιου ʮԿ͔ͷ৘ใʯΛʮͲ͏ͯ͠΄͍͠ʯ

Slide 16

Slide 16 text

[0]$ telnet cookpad.com 80 Trying 54.199.213.92... Connected to cookpad.com. Escape character is '^]'. GET / HTTP/1.1 Host: cookpad.com HTTP/1.1 301 Moved Permanently Content-Type: text/html; charset=iso-8859-1 Date: Wed, 22 Feb 2017 07:29:24 GMT Location: https://cookpad.com/ Server: Apache Content-Length: 228 Connection: keep-alive 301 Moved Permanently )551

Slide 17

Slide 17 text

‣ GET : Ͳ͏͢Δ ‣ ʮHTTPϝιουʯ ‣ GET=औಘɺPOST=࡞੒ɺPATCH=(Ұ෦)ஔ͖׵͑ɺDELETE=࡟আ ‣ / : ͳʹΛ ‣ ͜ͷ৔߹ɺhttp://cookpad.com ͷτοϓϖʔδ (&5

Slide 18

Slide 18 text

‣ HTTP/1.1 ‣ ௨৴͢ΔHTTPͷόʔδϣϯΛද͢ɻ޿͘࢖ΘΕ͍ͯΔͷ͸1.1 ‣ ݱ୅తͳ໰୊Λղܾ͢ΔͨΊHTTP/2΋ग़͖ͯͨ ‣ GET / HTTP/1.1 ͷߦΛʮϦΫΤετϥΠϯʯͱݺͿ ‣ Host: cookpad.com ‣ 1αʔόͰෳ਺αʔϏεΛӡ༻Ͱ͖ΔͨΊɺ࿦ཧతʹͲͷαʔϏε΁ͷϦΫΤετͰ͋Δ͔Λࣔ͢ඞཁ͕ ͋Δ ‣ ۭߦ ‣ ϦΫΤετ͕ऴΘͬͨ΋ͷͱͯ͠αʔόͷॲཧ͕࢝·Δ ͦͷଞͷՕॴ

Slide 19

Slide 19 text

‣ HTTPͰϦΫΤετ͏͚ɺαʔό্ͰͳΜΒ͔ͷॲཧ Λߦ͍ɺϨεϙϯεΛฦ͢ ‣ τοϓϖʔδ(/)͕΄͍͠(GET)ͱ͍͏ϦΫΤετʹͨ ͍ͯ͠ɺτοϓϖʔδͷHTMLΛੜ੒ͯ͠Ϩεϙϯε ͢Δͷ͕WebΞϓϦέʔγϣϯ 8FCΞϓϦέʔγϣϯ

Slide 20

Slide 20 text

‣ Railsͱ͸ɺRubyϓϩάϥϛϯάݴޠͰॻ͔ΕͨWebΞϓϦ έʔγϣϯϑϨʔϜϫʔΫͰ͢ɻRails͸ɺ͋ΒΏΔ։ൃऀ ͕WebΞϓϦέʔγϣϯͷ։ൃΛ࢝ΊΔ͏͑ͰඞཁͱͳΔ ࡞ۀ΍ϦιʔεΛࣄલʹԾఆͯ͠४උ͓ͯ͘͜͠ͱͰɺ WebΞϓϦέʔγϣϯΛΑΓ؆୯ʹϓϩάϥϛϯάͰ͖Δ Α͏ʹઃܭ͞Ε͍ͯ·͢ɻ ‣ -- http://railsguides.jp/getting_started.html

Slide 21

Slide 21 text

ඞཁͳϞϊΛԾఆͯ͠४උ
 ϑϧελοΫϑϨʔϜϫʔΫ

Slide 22

Slide 22 text

‣ Railsʹ͸ҰൠతͳWebΞϓϦέʔγϣϯʹඞཁͳػೳ͕
 Ұἧ͑ೖ͍ͬͯΔɻ ‣ HTTPϦΫΤετ͔ΒRubyͷॲཧΛݺͼग़͢͠ɺΫϥΠΞϯτʹ݁ՌΛ
 ฦͨ͢Ίͷ࢓૊Έ ‣ DBͷσʔλΛಡΈॻ͖͢Δ࢓૊Έ ‣ ॲཧ݁ՌΛHTML(ϒϥ΢β޲͚)΍JSON(ଞͷϓϩάϥϜ޲͚)Ͱ
 දݱ͢Δ࢓૊Έ ඞཁͳϞϊΛԾఆͯ͠४උϑϧελοΫ

Slide 23

Slide 23 text

‣ ҧ͍͸ʮ੍ޚͷํ޲ʯͱ͍͏͜ͱʹͳ͍ͬͯΔ ‣ ࣗ෼ͷॻ͍ͨίʔυͰݺͼग़͢ͷ͕ϥΠϒϥϦ ‣ ࣗ෼ͷॻ͍ͨίʔυΛݺͼग़ͯ͘͠ΕΔͷ͕ϑϨʔϜϫʔΫ ‣ Railsͩͱ: ϞσϧɺϏϡʔɺίϯτϩʔϥΛࣗ෼Ͱॻ͘ͱϢʔβͷ
 ϦΫΤετʹԠͯ͡ݺͼग़͞ΕΔ = MVCύλʔϯʹଇͬͨϑϨʔϜϫʔΫ ‣ (ͱ͸͍͑΍͍ͬͯΔ͏ͪʹϐϯͱདྷΔͱ͖͕͘ΔͷͰɺਂೖΓ͠ͳͯ͘Α͍) ༨ஊ ϥΠϒϥϦͱϑϨʔϜϫʔΫ

Slide 24

Slide 24 text

͓୊: ύʔιφϧϝϞΛ࡞Ζ͏

Slide 25

Slide 25 text

‣ ؆୯ͳRailsΞϓϦέʔγϣϯΛ࡞Δ ‣ ͦͷաఔͰWebΞϓϦʹඞཁͳॾ֓೦ʹ৮ΕΔ ‣ REST ‣ RDBMSઃܭ ͜ͷηογϣϯͰ΍Δ͜ͱ

Slide 26

Slide 26 text

‣ ඇಉظॲཧɺόονॲཧ ‣ JavaScript͘Θ͘͠ ‣ CSS͘Θ͘͠ ‣ RDBMSҎ֎ͷσʔλετΞ ‣ WebΞϓϦΛಈ͔͢Πϯϑϥ
 (Ϋϥ΢υɺεέʔϧΞ΢τɺίϯςφԽ) ͜ͷηογϣϯͰ΍Βͳ͍͜ͱ ཁࣗशPS͋ͱͰ࣭໰ͯ͠

Slide 27

Slide 27 text

ϝϞΛೖྗͰ͖Δ

Slide 28

Slide 28 text

‣ https://ghe.example.com/moro/memo2 ‣ Haml: HTML(XML)ͷग़ྗʹదͨ͠ςϯϓϨʔτݴޠ ‣ Bootstrap: Twitter͕ࣾఏڙ͍ͯ͠ΔCSSϑϨʔϜϫʔΫ SBJMTOFX͖ΐ͏࢖͏ϥΠϒϥϦΛ༻ҙ͓͖ͯ͠·ͨ͠

Slide 29

Slide 29 text

Slide 30

Slide 30 text

Slide 31

Slide 31 text

‣ αϯϓϧͷϦϙδτϦΛfork͠ɺࣗ෼ͷϦϙδτϦ͔Β
 clone͍ͯͩ͘͠͞ɻ ‣ RailsΞϓϦέʔγϣϯΛىಈͯ͠Έ·͠ΐ͏ɻ ‣ NewϦϯΫΛͨͲͬͯɺ͋ͨΒ͍͠ϝϞΛ1݅Ҏ্௥Ճ͠· ͠ΐ͏ɻ ࣮श0: 10෼

Slide 32

Slide 32 text

$ git clone https://ghe.example.com//memo2.git $ cd memo2 $ bundle install $ (brew services start postgresql) $ ./bin/rails db:create $ ./bin/rails db:migrate $ ./bin/rails s -p 3000 $ open http://localhost:3000/memos 3BJMTΞϓϦέʔγϣϯΛىಈ͠Α͏ ‣ Ͳ͏ͳ͍ͬͯΔ͔ɺϒϥ΢βͰݟͯΈ·͠ΐ͏

Slide 33

Slide 33 text

͜ͷαϯϓϧͰ ΍ͬͯ͋Δ͜ͱ

Slide 34

Slide 34 text

--- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,4 @@ Rails.application.routes.draw do + resources :memos # For details on the DSL available within this file, see http://guides.rubyon routing.html end 3BJMT͸3&45ͱ͍͏ߟ͑ํʹ΋ͱ͍͍ͮͯΔ ‣ 3&QSFTFOUBUJPOBM4UBUF5SBOTGFS ‣ )551ϝιου Ͳ͏͍ͨ͠ ͱύεΫΤϦ ͳʹΛ Λͱ͍͏૊Έ߹ΘͤΛɺ
 Ϧιʔε΁ͷૢ࡞ɺͱͯ͠ந৅Խ͠ɺΞʔΩςΫνϟͷத৺ʹஔ͘ߟ͑ํ ‣ ͦͷϦιʔε΁ͷૢ࡞Λ΋ͬͯɺΞϓϦέʔγϣϯͷॲཧΛ࣮ݱ͢Δɻ ‣ ࠓճ͸ɺѻ͏ϝϞNFNPΛɺͦͷ··Ϧιʔεͱͨ͠ɻ

Slide 35

Slide 35 text

$ ./bin/rails routes
 Prefix Verb URI Pattern Controller#Action memos GET /memos(.:format) memos#index POST /memos(.:format) memos#create new_memo GET /memos/new(.:format) memos#new edit_memo GET /memos/:id/edit(.:format) memos#edit memo GET /memos/:id(.:format) memos#show PATCH /memos/:id(.:format) memos#update PUT /memos/:id(.:format) memos#update DELETE /memos/:id(.:format) memos#destroy resources :memosͰఆٛ͞ΕΔૢ࡞ ‣ ෳ਺औಘɺ୯਺औಘɺ࡞੒ɺߋ৽ɺ࡟আ ‣ ࡞੒ɺߋ৽ͷͨΊͷϑΥʔϜΛؚΉը໘΋Ϧιʔεͱߟ͑ΒΕΔ ‣ /memos͕ϝϞͷू߹Λද͠ɺͦͷू߹Λऔಘ (&5 ͢Δ͜ͱΛ΋ͬͯɺ
 ʮϒϥ΢β্ʹϝϞΛҰཡදࣔʯͱ͍͏ΞϓϦέʔγϣϯͷॲཧΛදݱͨ͠ɻ

Slide 36

Slide 36 text

‣ POST /groups/42/add_member ‣ ϘσΟͰ person_id = 4Λࢦఆ͠ɺάϧʔϓͷ add_member ॲཧΛݺͼग़͢ ‣ POST /groups/42/memberships ‣ ϘσΟͰ person_id = 4Λࢦఆ͠ɺ"άϧʔϓʹࢀՃ ͍ͯ͠Δ͜ͱ"(membership)Λ࡞੒͢Δ ༨ஊ Ϧιʔε͸Ϟϊ͚ͩͰͳ͍

Slide 37

Slide 37 text

༨ஊ Ϧιʔε͸Ϟϊ͚ͩͰͳ͍

Slide 38

Slide 38 text

‣ registration (ొ࿥͢Δ͜ͱ)ΛϦιʔεͱͯ͠
 ѻ͍ͬͯΔɻ ‣ ొ࿥ɾೝূج൫ͳͷͰɻϦιʔεͱͯ͠ѻ͏΂͖͜ ͱͷཻ౓͸υϝΠϯ࣍ୈͰมΘΔɻ ‣ http://techlife.cookpad.com/entry/2017/04/06/172601 ༨ஊ Ϧιʔε͸Ϟϊ͚ͩͰͳ͍

Slide 39

Slide 39 text

+++ b/app/controllers/items_controller.rb @@ -0,0 +1,74 @@ +class MemosController < ApplicationController + before_action :set_memo, only: [:show, :edit, :update, :destroy] + + # GET /memos + # GET /memos.json + def index + @memos = Memo.all + end + *UFNT$POUSPMMFSJOEFY ‣ ϧʔςΟϯά͔Βݺ͹ΕΔͱ͖͸ANFNPTJOEFYAදه ‣ .FNP͸3BJMTඪ४ͷ03.ɺ"DUJWF3FDPSE#BTFΛܧঝͨ͠Ϋϥεɻ ‣ .FNPBMMͰɺNFNPTςʔϒϧͷશϨίʔυΛಡΈࠐΈɺ
 !NFNPTʹೖΕΔ

Slide 40

Slide 40 text

‣ ϑϨʔϜϫʔΫͷಈ͖Λ͢΂ͯઃఆ͢Δ(configuration)͢ΔͷͰͳ͘ɺ
 Rails͕૝ఆ͢Δن໿(convention)ʹԊͬͯಈ͘ɻ ‣ ARΫϥεMemo͸ memos ςʔϒϧͷϨίʔυΛѻ͏ ‣ GET /memos͸ MemosController#index ΛݺͼɺΞΫγϣϯॲཧޙ͸ app/ views/memos/index.html.* ͷςϯϓϨʔτΛϨϯμϦϯά͢Δ ‣ ม਺໊ͰܕΛදݱ͢ΔจԽ΋͋Δɻ ‣ Railsʹ׳ΕΔͱmemos͸ෳ਺ͷMemoΠϯελϯεΛ͋ΒΘ͢ม਺໊ͱ
 ಡΈऔΔɻ $POWFOUJPOPWFS$POpHVSBUJPO

Slide 41

Slide 41 text

‣ ςϯϓϨʔτΛฤूͨ͠͏͑Ͱϒϥ΢βΛϦϩʔυ͠ɺද ͕ࣔมΘΔ͜ͱΛ֬ೝ͠·͠ΐ͏ɻ ‣ layout ͷԾஔ͖ͷαΠυόʔΛফͯ͠ΈΑ͏ ‣ app/views/layouts/application.html.haml ‣ ૣ͘ऴΘͬͨΒ: τοϓϖʔδ(‘/‘)ͰϝϞͷҰཡΛදࣔͰ͖ ΔΑ͏ʹ͠·͠ΐ͏ɻ ࣮श1: 5෼

Slide 42

Slide 42 text

‣ lesson-[n]-nantoka ͳͲͷϒϥϯνͰ։ൃ͢Δɻ ‣ ࣗϦϙδτϦ΁ͷmasterͱͯ͠ɺPRΛ࡞Δɻ ‣ title΍description΋Կ͔ॻ͘ɻ ‣ Ͳͷ՝୊޲͚͔ΛΘ͔ΔΑ͏ʹ͓͍͍ͯͯͩ͘͠͞ɻ ‣ ͋ͱͰಡΜͩਓ޲͚ͷจ຺΍޻෉ͨ͜͠ͱ(೚ҙ)ͳͲɻ ‣ ࣗϦϙδτϦ΁ʹϚʔδ͢Δɻ ࣮शఏग़ํ๏

Slide 43

Slide 43 text

‣ RailsΛ࢖͍͸͡Ίͨ ‣ ͍ΖΜͳgem͕͋Δ ‣ Convention over Configuration ‣ RESTfulͳΞʔΩςΫνϟʹ;Εͨ ͜ͷεςοϓͰֶΜͩ͜ͱ

Slide 44

Slide 44 text

$ vim config/routes.rb Rails.application.routes.draw do root to: 'memos#index' resources :memos end ࢓্͛τοϓϖʔδͰϝϞͷҰཡΛදࣔ͠Α͏

Slide 45

Slide 45 text

Ϣʔβ͝ͱʹ
 ϝϞ͕औΕΔ

Slide 46

Slide 46 text

ߟ͑ΔʮϢʔβ͝ͱϝϞʯͷσʔλߏ଄ ユーザ タイトル 内容 Alice きょうやること - インターンに参加する - 懇親する Alice 買い出し ## 薬局 - 風邪薬 ## スーパー - 牛乳2本 - 卵があれば6つ Bob 明日の持ち物 印鑑

Slide 47

Slide 47 text

ߟ͑ΔʮϢʔβʯͷॏෳΛݮΒ͢ /' /' タイトル 内容 きょうやること - インターンに参加する - 懇親する 買い出し ## 薬局 - 風邪薬 ## スーパー - 牛乳2本 - 卵があれば6つ 明日の持ち物 印鑑 ユーザ Alice Bob

Slide 48

Slide 48 text

3BJMT෺ཧઃܭ1, ',Λಋೖ͢Δ id user_id タイトル 内容 1 1 きょうやること - インターンに参加する - 懇親する 2 1 買い出し ## 薬局 - 風邪薬 ## スーパー - 牛乳2本 - 卵があれば6つ 3 2 明日の持ち物 印鑑 id ユーザ 1 Alice 2 Bob

Slide 49

Slide 49 text

‣ ݱΫοΫύουͷActiveRecordϞσϧΫϥε(ҎԼARϞσϧ)User͸ϑΝΠϧத Ͱఆٛ͞ΕΔϝιου͕328ݸɺinclude͍ͯ͠ΔϞδϡʔϧ͕14ݸɺ175ݸͷؔ ࿈͕ఆٛ͞Ε͍ͯΔ3,000ߦΛ௒͑ΔΫϥεͰ͢ɻ ‣ υϝΠϯʹ͓͚ΔҙຯʹΑͬͯɺςʔϒϧ͸෼ׂ͍͖ͯ͠·͠ΐ͏ɻ ‣ Α͋͘Δྫ: users ςʔϒϧʹ email / password ͸͋Δ΂͖͔ ‣ Ұൠతʹ͸ɺগͳ͘ͱ΋࿦ཧઃܭͰ͸ࡉ͔͘෼͚͍ͯ͘΄͏͕ϕλʔɻ ༨ஊ Ϣʔβʔςʔϒϧʹ͋Δ΋ͷɺͦ͏Ͱͳ͍΋ͷ

Slide 50

Slide 50 text

$ ./bin/rails g model user name:string $ ./bin/rails g migration AddUserRefToMemos user:references $ ./bin/rails db:migrate VTFSTςʔϒϧͱɺNFNPTVTFS@JEΛ௥Ճ͢Δ

Slide 51

Slide 51 text

$ cat db/schema.rb create_table "memos", force: :cascade do |t| t.string "title" t.text "body" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "user_id" t.index ["user_id"], name: "index_memos_on_user_id", using: :btree end create_table "users", force: :cascade do |t| t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_foreign_key "memos", "users" VTFSTςʔϒϧͱɺNFNPTVTFS@JEΛ௥Ճ͢Δ

Slide 52

Slide 52 text

$ ./bin/rails console > User.create!(name: 'alice') > User.create!(name: 'bob') > exit ϢʔβͷμϛʔσʔλΛ࡞Δ

Slide 53

Slide 53 text

‣ ϢʔβΦϒδΣΫτ͔Βॴ༗͢ΔϝϞΛऔಘͰ͖ͨΓɺ
 ϝϞ͔ΒͦͷϢʔβΛऔಘͰ͖ͨΓ͢Δͱศར ‣ ActiveRecord Ͱ͸ςʔϒϧؒ(ARΫϥεؒ)ͷؔ࿈Λ
 දݱͰ͖Δ ‣ ARͰͷݴ͍ճ͠͸ Association ߟ͑ΔϢʔβ͝ͱʹϝϞ͕͋Δɺͱ͸

Slide 54

Slide 54 text

‣ ʮϝϞ͸1ਓͷϢʔβʹଐ͢Δʯ ‣ Memo belongs_to :user ‣ memos͕΋͍ͬͯΔuser_idʹΑͬͯɺଐ͢Δ1ਓͷϢʔβ Λࢀর͢Δ ‣ ϢʔβΛࢀর͢ΔͨΊͷ#userͱ͍͏ϝιουͳͲ͕࢖͑ ΔΑ͏ʹͳΔ ଟରPSରͷʮଐ͢Δʯؔ࿈ੑ

Slide 55

Slide 55 text

‣ ʮϢʔβ͸ɺෳ਺ͷϝϞΛॴ༗͍ͯ͠Δʯ ‣ User has_many :memos ‣ memos ͕΋͍ͬͯΔuser_id ʹΑͬͯɺॴ༗͢Δnݸ ͷϝϞΛࢀর͢Δ ‣ ෳ਺঎඼Λࢀর͢ΔͨΊͷ#memosͱ͍͏ϝιου ͳͲ͕࢖͑ΔΑ͏ʹͳΔ ରଟͷʮॴ༗͢Δʯؔ࿈ੑ

Slide 56

Slide 56 text

$ vim app/models/user.rb class User < ActiveRecord::Base has_many :memos end $ vim app/models/memo.rb class Memo < ActiveRecord::Base belongs_to :user end ؔ࿈Λઃఆ͢Δ

Slide 57

Slide 57 text

$ ./bin/rails console > user = User.find_by!(name: ‘alice') > user.name > user.memos > user.memos = Memo.all > memo = Memo.first > memo.user طଘͷϝϞ΋ಛఆͷϢʔβʹؔ࿈෇͚Δ

Slide 58

Slide 58 text

‣ ͜͜·Ͱͷઆ໌Λ΋ͱʹɺUserΫϥεΛ࡞੒͠ɺ
 ؔ࿈ͳͲΛఆٛ͠ͳ͍͞ɻ ‣ લͷϖʔδͷσʔλϚΠάϨʔγϣϯΛ͠Α͏ɻ ‣ ૣ͘ऴΘͬͨΒ: ‣ Rails guideͷʮActive Record ͷؔ࿈෇͚ʯΛ
 ಡΜͰΈΑ͏ ࣮श2: 15෼

Slide 59

Slide 59 text

Ϣʔβͱͯ͠ϩάΠϯͰ͖Δ

Slide 60

Slide 60 text

‣ ϩάΠϯૢ࡞ ‣ ϢʔβຊਓͷΈ͕஌͍ͬͯΔ৘ใͰೝূ͠ɺϩάΠϯঢ়ଶ ʹ͢Δૢ࡞ ‣ ϩάΠϯঢ়ଶ ‣ ͦͷαʔϏεΛ࢖͍ͬͯΔϢʔβΛɺ8FCΞϓϦ
 ͔ΒҰҙʹࣝผͰ͖Δঢ়ଶ ‣ ຊਓͷΈʹڐ͞Εͨૢ࡞΍Ϧιʔε΁ͷΞΫηε͕Ͱ͖Δ Α͏ʹͳΔ ϩάΠϯͱ͸Կ͔

Slide 61

Slide 61 text

‣ ʮϩάΠϯૢ࡞ʯ= ೝূͷ࣮૷͸΍Γ·ͤΜɻ
 ͍ΖΜͳ΋ͷ͕͋Δɻ ‣ Ϣʔβ໊ + ύεϫʔυ ‣ SNS (OAuth2 ΍ OpenID) ‣ ϫϯλΠϜύεϫʔυ+ϩάΠϯϦϯΫ ‣ SSLΫϥΠΞϯτೝূ ‣ ෺ཧσόΠε etc… ʲ஫ҙʳ͖ΐ͏΍Βͳ͍͜ͱ

Slide 62

Slide 62 text

‣ WebΞϓϦέʔγϣϯͰ͸ʮηογϣϯʯͱ͍͏
 ߟ͑ํͰ࣮ݱ͞ΕΔ͜ͱ͕ଟ͍ɻ ϩάΠϯঢ়ଶ

Slide 63

Slide 63 text

‣ େલఏ: HTTP͸ঢ়ଶΛ࣋ͨͳ͍ϓϩτίϧͰ͋Δɻ ‣ αʔόଆʹɺΫϥΠΞϯτঢ়ଶΛอ࣋Ͱ͖ͳ͍ɻ ‣ ෳ਺ฒΜͩαʔόͷͲΕʹϦΫΤετ͕ߦ͔ܾ͘ఆͰ͖ͳ͍ɻ ‣ ࣮༻తͳαʔϏεΛ࡞ΔͨΊʹ͸ɺٖࣅతʹʮঢ়ଶʯΛ
 ࣋ͨͤΔඞཁ͕͋Δɻ ‣ Ұ౓ϩάΠϯͨ͠Β͠͹Βͦ͘ͷਓͱͯ͠ೝূ͞Ε͍ͯΔɺͱ͔ɻ ‣ ͜ͷʮ͋Δ࣌ؒ୯ҐͰಉҰϢʔβ͕ܧଓతʹαʔϏεΛ࢖ͬ ͍ͯΔঢ়ଶʯΛηογϣϯͱݺͿɻ ηογϣϯͱ͸

Slide 64

Slide 64 text

‣ ΫϥΠΞϯτ(ϒϥ΢β)͕ৗʹૹग़͢ΔσʔλʹࣝผࢠΛ ೖΕɺαʔόଆͰΫϥΠΞϯτঢ়ଶΛอଘ͢Δ͜ͱͰ
 ʮηογϣϯʯΛදݱ͍ͯ͠Δɻ ‣ CookieΛར༻͢Δ͜ͱ͕ଟ͍ɻ ‣ WebΞϓϦϑϨʔϜϫʔΫ͕ػೳΛఏڙͯ͘͠ΕΔɻ CookieʹΑΔʮηογϣϯʯͷ࣮ݱ

Slide 65

Slide 65 text

Slide 66

Slide 66 text

Slide 67

Slide 67 text

‣ WebΞϓϦʹ͓͍ͯɺαʔό͕ΫϥΠΞϯτʹ
 ʮ࣍ʹૹͬͯ΄͍͠σʔλʯΛ౉ͤΔɻ ‣ Set-Cookie: ϔομ ‣ ΫϥΠΞϯτ͸࣍ͷϦΫΤετ࣌ʹ Cookie ϔομʹͦͷσʔλΛೖΕͯૹΔ ‣ ※ ཁ͸ΫϥΠΞϯτ͕೚ҙͷσʔλΛૹ৴Ͱ͖Δɻ Cookie

Slide 68

Slide 68 text

‣ ίϯτϩʔϥͷ #session ͰΞΫηεͰ͖Δɻ ‣ ෳ਺ϦΫΤετΛލ͍ͰσʔλΛอ࣋Ͱ͖Δɻ ‣ ͋·Γͨ͘͞ΜͷσʔλΛೖΕͳ͍ͷ͕Rails way ‣ ϩάΠϯϢʔβͷid΍ɺ஫จͷidͳͲ ‣ ϦΫΤετΛड͚ͨ͋ͱidͰDB͔ΒҾ͖௚ͯ͠࢖͏ RailsͰͷηογϣϯ࣮૷

Slide 69

Slide 69 text

 (1) Cookie: (なし) (2) uid=42なセッション開始 (3) {uid: 42} をキー abcdeで保存 (4) Set-Cookie: sid=abcde (5) Cookie: sid=abcde (6) キーabcdeでセッション データを検索 (7) {uid: 42} として処理 Ұൠతͳηογϣϯͷ࣮ݱ

Slide 70

Slide 70 text

(1) Cookie: (なし) (2) uid=42なセッション開始 (3) Set-Cookie: {uid: 42} (4) Cookie: {uid: 42} (6) 署名を検証 (7) {uid: 42} として処理 RailsͷCookieετΞηογϣϯ

Slide 71

Slide 71 text

‣ લड़ͷΑ͏ʹɺCookie͸UA(ϒϥ΢β)͕ೖΕͯ͘Δ ʮϢʔβʔ͔Βͷೖྗ஋ʯͰ͋Δɻ ‣ Rails ͷηογϣϯ͸ɺηογϣϯΩʔΛ༧ଌෆೳͳ ஋ʹͨ͠Γɺվ͟Μ๷ࢭͷ࢓૊ΈΛೖΕ͍ͯΔ (CookieετΞ)ɻ ‣ ଞͷϔομ΋ಉ༷ɻ (༨ஊ) ϔομ΍Cookie ΋վ͟ΜͰ͖Δ

Slide 72

Slide 72 text

‣ αʔϏεҰൠʹ͓͍ͯʮҰ࿈ͷϢʔβʔߦಈʯΛࢦ͢
 (֓೦)ηογϣϯɻ ‣ ֓೦ʙͷߦಈͷؒͰͰσʔλΛ࣋ͪճͨ͢ΊʹWebͰ͸ CookieͳͲͰ࣮ݱ͞ΕΔ(ػೳ)ηογϣϯɻ ‣ ػೳʙΛ࣮ݱ͢ΔͨΊʹɺRailsఏڙ͢Δ`#session`ϝιου ͳͲ(Rails࣮૷)ηογϣϯɻ ͍ΖΜͳηογϣϯؔ܎͋Δ͚ͲҐ૬͕ҧ͏ͷͰ஫ҙ

Slide 73

Slide 73 text

$ vim config/routes.rb
 # REST的に考えると「ログインする」のは(概念)セッションを作ること # 1ブラウザにつき1個なので単数リソース Rails.application.routes.draw do root to: 'memos#index' resources :memos resource :session end ࣮૷ͯ͠ΈΑ͏

Slide 74

Slide 74 text

$ vim app/views/sessions/new.html.haml = form_tag session_path, class: "form-horizontal" do .form-group .col-lg-offset-2.col-lg-4 %label ログインユーザ - opts = options_for_select(User.all.map {|u| [u.name, u.id] }) = select_tag :user_id, opts, class: 'form-control' .form-group .col-lg-offset-2.col-lg-10 = submit_tag 'ログインする', class: 'btn btn-primary' = link_to 'キャンセル', root_path, class: 'btn btn-default' $ vim app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end end $ open http://localhost:3000/session/new ϩάΠϯϑΥʔϜ͸TFTTJPOTOFXʹ͢Δ

Slide 75

Slide 75 text

$ tail -f log/development.log ϩάΛݟͳ͕Β࡞ۀ͠·͠ΐ͏

Slide 76

Slide 76 text

‣ (؆қ)ೝূ͢ΔΞΫγϣϯɺ `SessionsController#create`Λ࣮૷͠Α͏ ‣ ౉͞Ε͖ͯͨ user_id Ͱfindͯ͠sessionʹೖΕΔ ‣ ૣ͘ऴΘͬͨΒ: ‣ φϏήʔγϣϯόʔʹ͜ͷϩάΠϯը໘΁ͷϦϯΫΛ͚ͭΑ͏ɻ ‣ RailsΨΠυͷηΩϡϦςΟ߲ΛಡΈɺηογϣϯݻఆ߈ܸʹֶ͍ͭͯ΅͏ ‣ ϩάΞ΢τͰ͖ΔΑ͏ʹ͠Α͏ ࣮श3: 20෼

Slide 77

Slide 77 text

class SessionsController < ApplicationController def new end def create user = User.find_by(id: params[:user_id]) if user reset_session session[:user_id] = user.id redirect_to root_path, notice: 'Login successed' else redirect_to root_path, alert: 'Login failed' end end end ճ౴ྫ

Slide 78

Slide 78 text

# —- リンク = link_to "ログアウト", session_path, method: :delete ͪͳΈʹϩάΞ΢τ

Slide 79

Slide 79 text

‣ ϩάΠϯதͷϢʔβΛը໘ʹදࣔ͠Α͏ ‣ session[:user_id]ͰҾ͖ɺίϯτϩʔϥͷΠϯελϯεม਺ʹೖΕΔ or ΞΫηαϝιουΛ࡞Ζ͏ ‣ ׳ྫͩͱ current_user ͱ͍͏໊લ ‣ Railsίϯτϩʔϥͷ helper_method એݴΛௐ΂ͯΈΑ͏ ‣ શίϯτϩʔϥͰ࢖͏ͨΊʹ ApplicaitionController ʹఆٛ͠Α͏ ‣ ը໘ͷͲ͔͜Ͱදࣔ͠Α͏ ‣ ૣ͘ऴΘͬͨΒ: ‣ ϩάΠϯঢ়ଶΛ൑ఆ͢ΔϝιουΛ࡞Ζ͏ ‣ φϏήʔγϣϯόʔͷϩάΠϯϦϯΫΛɺϩάΠϯத͸ϩάΞ΢τϦϯΫʹ͠Α͏ ࣮श4: 30෼

Slide 80

Slide 80 text

class ApplicationController < ActionController::Base protect_from_forgery with: :exception helper_method :logged_in?, :current_user private def logged_in? current_user.present? end def current_user if session[:user_id] @current_user ||= User.find(session[:user_id]) end end end ճ౴ྫϝιουԽͯ͠

Slide 81

Slide 81 text

%ul.nav.navbar-nav.navbar-right - if logged_in? %li %p.navbar-text Hello %strong= current_user.name %li= link_to "ログアウト", session_path, method: :delete - else %li= link_to "ログイン", new_session_path .container ճ౴ྫϏϡʔͰදࣔͰ͖ΔΑ͏ʹͨ͠

Slide 82

Slide 82 text

‣ ActiveRecordͰ User has_many memos ؔ࿈͕͋Δͱ ‣ user.memos ͰϢʔβʹؔ࿈͍ͮͨϝϞΛҾ͚Δ ‣ user.memos.create! ͰϢʔβʹؔ࿈͍ͮͨϝϞΛ
 ࡞ΕΔ Ϣʔβ͝ͱʹϝϞΛ࡞Ζ͏

Slide 83

Slide 83 text

‣ ࡞੒͢ΔϝϞΛɺϩάΠϯதͷϢʔβʹؔ࿈෇͚· ͠ΐ͏ɻ ‣ ૣ͘ऴΘͬͨΒ: ‣ ϝϞҰཡͰදࣔͰ͖ΔϝϞΛɺϩάΠϯதϢʔβ͚ͩͷ΋ͷʹ͠·͠ΐ͏ɻ ‣ ฤूɺ࡟আͰ͖ΔͷΛࣗ෼ͷϝϞ͚ͩʹ͠·͠ΐ͏ ࣮श5: 30෼

Slide 84

Slide 84 text

ϝϞΛڞ༗Ͱ͖Δ

Slide 85

Slide 85 text

‣ ϝϞ࡞ऀͱͯ͠ɺڞ༗Ͱ͖Δɻ ‣ ڞ༗͞Εͨଆͱͯ͠ɺϝϞͷ಺༰ΛදࣔͰ͖Δɻ ‣ ฤूɾ࡟আ͸Ͱ͖ͳ͍ ߟ͑Δʮڞ༗ʯͷ࢓༷Λߟ͑Δ

Slide 86

Slide 86 text

‣ ʮڞ༗͢Δʯखஈͱͯ͠ʮൿີͷURLʯΛ࡞੒͢Δɻ ‣ ϝϞ࡞ऀ͸ɺಛఆͷϝϞΛڞ༗ऀʹݟͤΔͨΊͷ
 ʮൿີͷURLʯΛൃߦͰ͖Δɻ ‣ ڞ༗ଆ͸ɺͦͷURLʹΞΫηε͢ΔͱϝϞͷ಺༰ΛදࣔͰ ͖Δɻ ࢓༷͔Β࣮૷Λߟ͑Δ

Slide 87

Slide 87 text

‣ ʮڞ༗͞ΕͨϝϞʯ͸Ͳ͏͍͏Ϧιʔεͳͷ͔ɻ ‣ Ͳ͏ଊ͔͑ͨɺPRʹॻ͍͓͍͍ͯͯͩ͘͞ɻ ‣ ൿີͷURLʹظݶ͸͋Δ͔? ‣ ෳ਺ͷൿີͷURL͸ൃߦͰ͖Δ΂͖͔? ‣ ߋ৽ʹ௥ਵ͢΂͖͔? ࣮૷Λߟ͑Δ ଓ͖

Slide 88

Slide 88 text

‣ (ERਤ) secret_memos belongs_to memos ‣ uuid ‣ expires_at ‣ … ‣ ଟॏ౓Ͳ͏͢ΔɺফͤΔ?… %#ઃܭ

Slide 89

Slide 89 text

memos title:string body:text rails timestamps secret_links memo_id:integer uuid:string …? rails timestamp * 1

Slide 90

Slide 90 text

‣ ࡞੒ͨ͠ϝϞΛڞ༗Ͱ͖ΔΑ͏ʹ͠·͠ΐ͏ɻ ‣ ϝϞ࡞ऀ͕ൿີͷURLΛൃߦͰ͖Δ ‣ ڞ༗͞Εͨଆ͕ϝϞͷ಺༰ΛݟΒΕΔ ‣ ͦͷଞʮϝϞͷڞ༗ʯͱͯ͠ద੾ͩΖ͏࢓༷Λ
 ߟ࣮͑૷͠ͳ͍͞ ࣮श6: ऴΘΔ·Ͱ

Slide 91

Slide 91 text

‣ RailsΛ࢖ͬͯ؆୯ͳWebΞϓϦέʔγϣϯΛ࡞Δɻ ‣ ͦΕΛ௨ͯ͡ɺWebΞϓϦέʔγϣϯʹඞཁͳཁૉ ٕज़ʹ;ΕΔɻ ‣ REST: αʔϏεͷཁૉΛʮϦιʔεͷಡΈॻ͖ʯͱଊ͑Δ ‣ DBઃܭ: ਖ਼نԽͨ͠σʔλΛARܦ༝Ͱ͞ΘΔ ‣ ηογϣϯ: HTTPͰΫϥΠΞϯτঢ়ଶΛѻ͏ఆ൪Λ஌Δ ࠓ೔ͷΰʔϧ

Slide 92

Slide 92 text

‣ Git ‣ ϦϏδϣϯΛ؅ཧ͢Δ࢓૊Έɻcommit ͑͋͞Ε͹ ͳΜͱ͔ͳΔɻίϥϘϨʔγϣϯؤுΖ͏ɻ ‣ TDD ‣ ςετͰ։ൃΛʮۦಈʯ͢Δɻ։ൃɾઃܭख๏ɻ ‣ WebͱRails ‣ ৭ʑਂಡΈ͍ͯ͘͠ͱ͓΋͠Ζ͍Ͱ͠ΐɻ ࠓ೔ͷΰʔϧ ऴ೔

Slide 93

Slide 93 text

͓ർΕ͞·Ͱͨ͠