cookpad 2015 summer internship rails

cookpad 2015 summer internship rails

17eb0c1a9d70a94ce95401d046375e3c?s=128

Yoshiori SHOJI

August 20, 2015
Tweet

Transcript

  1. Rails

  2. ࠷ॳʹ

  3. Rails νϡʔτϦΞϧ1 ΍Ζ͏ ͱ͍͏ͷΛ·͓͍֮ͣ͑ͯͯ(࠷ޙʹ΋ݴ͏͚Ͳ) 1 http://railstutorial.jp/

  4. Կނ͔ 1. ࠓ೔͚ͩͰ৭ʑͳ͜ͱΛڭ͑·͢ɻ 2. Ұؾʹ֮͑Δͷ͸ແཧͰࣗ৴Λࣦ͏͔΋͠Ε·ͤΜɻ 3. ͔͠΋໌೔͔Β͸ Rails ࿔Γ·ͤΜɻ 4.

    ͱ͍͏Θ͚ͰɺRails ๨Ε͔͚ͯΔͱࢥͬͨΒ Rails νϡʔ τϦΞϧ1 Λࢥ͍ग़͢ͱྑ͍Ͱ͠ΐ͏ɻ 1 http://railstutorial.jp/
  5. HTTP ʹ͍ͭͯ

  6. HTTP(Hypertext Transfer Protocol) ͬ͘͟Γઆ໌ 1. αʔόͱΫϥΠΞϯτͰ΍ΓͱΓ͢Δ௨৴ϓϩτίϧ 2. hypertext ͱ͔ݴͬͯΔ͚ͲόΠφϦ΋ૹͬͯΔͷͰؾʹ ͠ͳ͍Ͱ͓̺

    3. ϒϥ΢βɺΞϓϦͱαʔόͰ΍ΓͱΓ͢Δن֨Ͱ͢
  7. HTTP(Hypertext Transfer Protocol) ͸·ΓͲ͜Ζ 1. εςʔτϨεͳϓϩτίϧͰ͢ 2. ௨৴Λ։࢝ग़དྷΔͷ͸ΫϥΠΞϯτ͔ΒͷΈͰ͢

  8. 1. εςʔτϨεͳϓϩτίϧͰ͢ ঢ়ଶΛ࣋ͪ·ͤΜ…… ͱ͔ݴΘΕͯ΋Θ͔Γʹ͍͘ͱࢥ͏ͷ Ͱ

  9. None
  10. 2. ௨৴Λ։࢝Ͱ͖Δͷ͸ΫϥΠΞ ϯτ͔ΒͷΈͰ͢ 1. ͳͷͰ push ௨஌ͳͲ͸ग़དྷ·ͤΜ 2. push ௨஌ͬΆ͍෺Λ΍ΔͨΊʹ͸৭ʑେมʢServer

    Sent Events ͱ͔ௐ΂Δͱ৭ʑग़ͯ͘Δʣ
  11. HTTP(Hypertext Transfer Protocol) ৮ͬͯΈ·͠ΐ͏ $ telnet cookpad.com 80 Trying 54.65.132.171...

    Connected to cookpad.com. Escape character is '^]'. ͦͷ··ԼهͷΑ͏ʹଧͬͯΈ·͢ɻ GET / HTTP/1.1 Host: cookpad.com ͦͷޙɺReturn key Λೋճԡ͠·͢ɻ ͩΒʙ ͬͱΫοΫύουͷσʔλ͕औಘग़དྷ·ͨ͠ɻ
  12. HTTP(Hypertext Transfer Protocol) 4 1ߦ໨ʢϦΫΤετߦʣ 4 GETʢHTTP ϝιουʣ 4 /

    (Path) 4 HTTP/1.1 ʢϓϩτίϧ໊ʣ 4 ೋߦ໨Ҏ߱ʢϝοηʔδϔομʣ 4 Host: cookpad.comʢϗετϔ ομʣ
  13. HTTP(Hypertext Transfer Protocol) Path ෦෼Λม͑ͯΈ·͠ΐ͏ GET /search HTTP/1.1 Host: cookpad.com

    ऴྃ͸ Ctrl + ] Λ͓ͨ͠ޙʹ quit ͱίϚϯυΛଧͯ͹ग़དྷ· ͢ɻ
  14. HTTP(Hypertext Transfer Protocol) HTTP ϝιου෦෼Λม͑ͯΈ·͠ΐ͏ HEAD /search HTTP/1.1 Host: cookpad.com

    ಉ͡ Path Ͱ΋ GET ͷ࣌ͱ͸ҧ͏΋ͷ͕ฦ͖ͬͯ·ͨ͠ɻ
  15. REST ࢥ૝ʹ͍ͭͯ

  16. REST ࢥ૝ʹ͍ͭͯ ͬ͘͟Γઆ໌ 4 ૢ࡞ͷର৅ͱͳΔϦιʔεΛ URL Ͱදݱ͢Δ 4 ͦΕʹ HTTP

    ͷϝιουΛ࢖ͬͯૢ࡞͢Δ
  17. REST ࢥ૝ʹ͍ͭͯ ྫ͑͹ /items/5 ͱ͍͏ URL ͕Ұͭͷ item Λද͍ͯͯ͠ 4

    HTTP ϝιουͷ GET ͰΞΫηε͢Δͱͦͷ item ͕औಘ Ͱ͖Δ 4 HTTP ϝιουͷ PATCH ͰΞΫηε͢Δͱͦͷ item ͷ৘ ใΛߋ৽Ͱ͖Δ 4 HTTP ϝιουͷ DELETE ͰΞΫηε͢Δͱͦͷ item Λ ࡟আͰ͖Δ
  18. REST ࢥ૝ʹ͍ͭͯ ಉ͡Α͏ʹ /items ͱ͍͏ URL ͸ item ͷू߹Λද͍ͯ͠ΔͷͰ 4

    HTTP ϝιουͷ GET ͰΞΫηε͢Δͱ item ͷू߹ʢҰ ཡʣ͕औಘͰ͖Δ 4 ྫ͑͹ /items/1, /items/2, /items/3, /items/4 …… ౳ 4 HTTP ϝιουͷ POST ͰΞΫηε͢Δͱ item ͷू߹ʹ৽͠ ͍ item Λ௥Ճ͢Δ ͱ͍͏;͏ʹͳΓ·͢
  19. Rails

  20. Rails ͷ MVC ੌ͘୯७ʹॲཧΛॻ͘ͱ…… 4 controllerʢͱ routesʣ ͸Ϣʔβʔ͔ΒͷೖྗΛݩʹ model Λऔಘ͠ɺview

    ʹ౉͠·͢ 4 view ͸౉͞Εͨ model Λදࣔ͠·͢ ͱ͍͏ಈ͖Λ͠·͢ɻ୯७Ͱ͢Ͷɻ
  21. ͬͦ͘͞ Rails ΞϓϦΛ࡞Γ·͠ΐ ͏ ࠓճ࡞ΔΞϓϦ͸ը૾ͷ URL Λ౤ߘͯ͠ΈΜͳͰͦͷը૾ʹίϝϯτ͕ ग़དྷΔΞϓϦέʔγϣϯʹͳΓ·͢ɻ ͖͞΄Ͳͷ REST

    తʹݴ͏ͱϦιʔε͸ 4 ը૾ͷ URL 4 ը૾ͷ URL ʹର͢Δίϝϯτ ͷ 2 ͭʹͳΓ·͢ɻ
  22. ͬͦ͘͞࡞Γ͸͡Ί·͠ΐ͏ $ rails new bokete -T Ͱ Rails ΞϓϦͷͻͳܗ͕ग़དྷ·͢ɻ $

    cd bokete ͯͦ͠ͷσΟϨΫτϦʹೖΓ·͢ɻ ࠓޙ͸͜ͷσΟϨΫτϦΛΞϓϦέʔγϣϯͷ HOME ͱͯ͠ ѻ͍جຊతʹ͸͜͜ͰίϚϯυΛ࣮ߦ͠·͢ɻ
  23. Bundler ৭ʑͳϥΠϒϥϦΛूத؅ཧͯ͘͠ΕΔ΋ͷͰ͢ɻ ·ͣ͸ Rspec ͱ haml Λ௥Ճ͠·͢ɻ Gemfile ʹԼهΛ௥ه͠·͢ gem

    "haml-rails", "~> 0.9" gem 'rspec-rails', '~> 3.0', group: [:development, :test]
  24. haml Խ Gemfile هࡌޙɺԼهΛ࣮ߦ͠·͢ $ bundle install ͜ΕͰϥΠϒϥϦͷΠϯετʔϧ͕ऴΘΓ·ͨ͠ɻ ࣍ʹςϯϓϨʔτΛ haml

    ʹ౷Ұ͠·͢ (ݩʑ͸ ERB ͩͬͨ΋ͷΛ haml ʹίϯόʔτ͠·͢) $ rails generate haml:application_layout convert $ rm app/views/layouts/application.html.erb
  25. Ұ୴֬ೝ $ rails server Λ࣮ߦ͠ɺىಈΛ֬ೝͰ͖ͨΒ http://localhost:3000 ʹΞΫηεͯ͠Έ·͠ΐ͏ɻ

  26. RSpec ४උ $ rails generate rspec:install Ͱ rspec ͷॳظԽΛߦ͍·͢ $

    bundle exec rspec Ͱ GREEN Λ֬ೝͨ͠Β commit ͓͖ͯ͠·͠ΐ͏ $ git init $ git add . $ git commit -m "init"
  27. image Ϟσϧ࡞੒

  28. image Ϟσϧ࡞੒ ը૾ URL ͱ λΠτϧΛอ࣋͢ΔϞσϧΛ࡞੒͠·͢ɻ $ rails generate model

    image url:string title:string invoke active_record create db/migrate/xxxxxxxxxxx_create_images.rb create app/models/image.rb invoke rspec create spec/models/image_spec.rb DB ͷߏ଄Λมߋ͢Δ migration ϑΝΠϧͱϓϩάϥϛϯά͔Β DB ͷσʔλΛૢ࡞͢ΔϞσϧ͕࡞੒͞Ε·ͨ͠ɻ
  29. image Ϟσϧ࡞੒ DB ఆٛ ઌͣ͸ DB ͷߏ଄Λมߋ͢Δ migration ϑΝΠϧΛ࿔Γ·͢ db/migrate/xxxxxxxxxxxcreateimages.rb

    Λ։͖ url ͱ title ΧϥϜΛ NOT_NULL ʹ͠·͢ class CreateImages < ActiveRecord::Migration def change create_table :images do |t| t.string :url, null: false # ௥Ճ t.string :title, null: false # ௥Ճ t.timestamps null: false end end end
  30. image Ϟσϧ࡞੒ DB ఆٛ ࣮ࡍʹσʔλϕʔεʹ migration ϑΝΠϧΛ൓ө͠·͢ɻ ࠓճ͸ςετ༻ͷ DB ʹ൓өͤ͞·͢

    $ bin/rake db:migrate RAILS_ENV=test rspec ࣮ߦͯ͠Έ·͠ΐ͏ $ bundle exec rspec pending ʹͳΓ·͢Ͷʢmodel Կ΋࣮૷͍ͯ͠ͳ͍ͷͰʣ
  31. image Ϟσϧ࡞੒ όϦσʔγϣϯ ͬͦ͘͞ model Λ࣮૷͍͖ͯ͠·͠ΐ͏ɻDB ͷ੍໿ΛϰΝϦσʔγϣϯ͠·͢ɻ require 'rails_helper' RSpec.describe

    Image, type: :model do describe "validation" do describe "url" do let(:no_url_image) { Image.new(url: nil, title: "title") } it "require url" do expect(no_url_image).to_not be_valid expect(no_url_image.errors[:url]).to_not be_empty end end end end rspec Λ࣮ߦ͢Δͱ੺͘ͳΓ·͢Ͷ
  32. image Ϟσϧ࡞੒ όϦσʔγϣϯ valid Ͱ͸ͳ͍͜ͱΛظ଴ͨ͠ͷʹ valid ͩͬͨͱݴΘΕ·͢Ͷɻ validation Λ model

    ʹ௥Ճ͠ valid Ͱ͸ແ͘͠·͠ΐ͏ɻ class Image < ActiveRecord::Base validates :url, presence: true end ಉ͡Α͏ʹ title ͷ ϰΝϦσʔγϣϯ΋࣮૷͠·͠ΐ͏ɻ rspec Λ࣮ߦ͢͠΂ͯ௨Δ͜ͱΛ֬ೝͯ͠ίϛοτ͠·͢ɻ $ git add . $ git commit -m "Add image model"
  33. Image ίϯτϩʔϥʔ࡞੒ ͬͦ͘͞࡞ͬͨϞσϧΛදࣔ͢ΔػೳΛ࡞Γ·͢ɻ Images Λѻ͏ ImagesController Λ࡞੒͠·͢ɻ app/controllers/images_controller.rb class ImagesController

    < ApplicationController end
  34. Image ίϯτϩʔϥʔ࡞੒ Spec ΋༻ҙ͠·͢ spec/controllers/images_controller_spec.rb require 'rails_helper' RSpec.describe ImagesController, type:

    :controller do describe "#index" do it "assigns @images" do get :index expect(assigns(:images)).to_not be_nil end end end ςετͷ಺༰ͷઆ໌͸ޙ΄Ͳ͠·͢ͷͰͱΓ࣮͋͑ͣߦͯ͠Έ·͠ΐ͏
  35. routes ͱ resources Failure/Error: get :index ActionController::UrlGenerationError: No route matches

    {:action=>"index", :controller=>"images"} images ͱ͍͏ controller ͷ index ͍ͬͯ͏ action ʹϚον ͢Δ route ͕ແ͍ΑͱݴΘΕ·͢ɻ
  36. routes ͱ resources config/routes.rb ͱ͍͏ϑΝΠϧʹԼهΛ͔͍ͯΈ·͢ Rails.application.routes.draw do resources :images end

    ͪΐͬͱલʹઆ໌ͨ͠ʮREST ࢥ૝ʹ͍ͭͯʯΛࢥ͍ग़͍ͯͩ͘͠͞ 4 ૢ࡞ͷର৅ͱͳΔϦιʔεΛ URL Ͱදݱ͢Δ 4 ͦΕʹ HTTP ͷϝιουΛ࢖ͬͯૢ࡞͢Δ routes ʹ images ͱ͍͏ϦιʔεΛૢ࡞͢Δͱઃఆͨ͠Θ͚Ͱ͢ɻ
  37. routes ͱ resources $ rake routes Prefix Verb URI Pattern

    Controller#Action images GET /images(.:format) images#index POST /images(.:format) images#create new_image GET /images/new(.:format) images#new edit_image GET /images/:id/edit(.:format) images#edit image GET /images/:id(.:format) images#show PATCH /images/:id(.:format) images#update PUT /images/:id(.:format) images#update DELETE /images/:id(.:format) images#destroy Ͳͷ HTTP ϝιουͰͲͷ URL ʹɺΞΫηε͢ΔͱɺͲͷ Controller ͷɺͲͷ Action ͕ݺ͹ΕΔͷ͔ग़͖ͯ·ͨ͠ɻ
  38. routes ͱ resources spec Ͱ֬ೝ͍ͯ͠Δͷ͸ GET ϝιουͰ index ʹΞΫηε͢Δͷ΋Ͱͨ͠ɻ ͜Ε͸

    URI Pattern ͱͯ͠͸ /images ʹͳΓ·͢ɻ ͜Ε͸ઌఔͷʮREST ࢥ૝ʹ͍ͭͯʯͰݴ͏ͱ 4 HTTP ϝιουͷ GET ͰΞΫηε͢Δͱ item ͷू߹ʢҰཡʣ͕औಘͰ͖ Δ 4 ྫ͑͹ /items/1, /items/2, /items/3, /items/4 …… ౳ ʹͳΓ·͢ɻ Ͱ͸ɺroute Λઃఆͨ͠ͷͰ rspec Λ࣮ߦͯ͠Έ·͠ΐ͏ɻ
  39. Image ίϯτϩʔϥʔ࡞੒ Failure/Error: get :index AbstractController::ActionNotFound: The action 'index' could

    not be found for ImagesController ImagesController ʹ index ΞΫγϣϯ͕ແ͍ͱݴΘΕ·ͨ͠ɻ ௥Ճ͠·͠ΐ͏ class ImagesController < ApplicationController def index end end rspec Λ࣮ߦͯ͠Έ·͠ΐ͏ɻ
  40. Image ίϯτϩʔϥʔ࡞੒ Failure/Error: get :index ActionView::MissingTemplate: Missing template images/index, application/index

    with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :haml, :jbuilder]}. Searched in: * "#<RSpec::Rails::ViewRendering::EmptyTemplatePathSetDecorator:0x007fdcbde03d90>" ࠓ౓͸ Template ͕ແ͍ͱݴΘΕ·ͨ͠ app/views/images/index.html.haml ͱ͍͏ϑΝΠϧΛ࡞Γ ·͢ rspec Λ࣮ߦͯ͠Έ·͠ΐ͏ɻ
  41. Image ίϯτϩʔϥʔ࡞੒ Failure/Error: expect(assigns(:images)).to_not be_nil expected: not nil got: nil

    ࠓ౓͸ ͳʹ΍Β not nil Λظ଴͍ͯ͠Δͷʹ nil ͩͱݴΘΕ·ͨ͠ɻ ͯ͞ɺઌ΄Ͳͷ spec Ͱ͕͢ get :index expect(assigns(:images)).to_not be_nil GET ϝιουͰ index ʹΞΫηεͨ͠Β imagesʢimage ͷू߹ʣ͕ΞαΠ ϯ͞Ε͍ͯΔ͜ͱΛ֬ೝ͍ͯ͠·ͨ͠ɻ
  42. Image ίϯτϩʔϥʔ࡞੒ Ͱ͸࣮ࡍʹΞαΠϯͯ͠Έ·͠ΐ͏ class ImagesController < ApplicationController def index @images

    = Image.all end end rspec Λ࣮ߦͯ͠Έ·͠ΐ͏ɻ͢΂ͯ௨Γ·͢Ͷɻ
  43. index view ࡞੒ ςετ͕͢΂ͯ௨ͬͨͷͰ࣮ࡍʹ֬ೝͯ͠Έ·͢ɻ ·ͣ͸։ൃ؀ڥͷ DB ΛηοτΞοϓ͠ىಈͯ͠Έ·͢ɻ $ bin/rake db:migrate

    RAILS_ENV=development $ rails server http://localhost:3000/images/ ʹΞΫηεͯ͠Έ·͠ΐ͏ɻ
  44. index view ࡞੒ ·ͩ view ΛԿ΋࡞͍ͬͯͳ͍ͷͰදࣔ͞Εͳ͍ͷ͸౰ͨΓલͰ͢Ͷɻ ·ͣ͸ app/views/images/index.html.haml ʹ %h1

    ը૾Ұཡ ͱɺॻ͍ͯϦϩʔυͯ͠Έ·͠ΐ͏ɻ
  45. index view ࡞੒ haml ʹ͍ͭͯ ͬ͘͟Γ 4 html tag ߏ଄Λ

    YAML ͬΆ͘දͨ͠ςϯϓϨʔτΤϯδϯ 4 % Ͱී௨ʹλά -> %ul 4 - Ͱ ruby ͷߏจ -> - @images.each do |image| 4 = Ͱ ग़ྗ -> = image.title
  46. index view ࡞੒ Image ͕Ұͭ΋σʔλϕʔεʹొ࿥͍ͯ͠ͳ͍ͷͰͦ΋ͦ΋Ұཡʹ΋ग़͢͜ͱ͕ग़དྷ·ͤΜɻ ొ࿥ͯ͠Έ·͠ΐ͏ɻ $ rails console Loading

    development environment (Rails 4.2.2) irb(main):001:0> Image.create!(url: "http://i.giphy.com/I6l7Kwu0GLvAA.gif", title: "starwars") index.html.haml ʹදࣔ෦෼Λ௥Ճ͠·͢ %h1 ը૾Ұཡ %dl - @images.each do |image| %dt= image.title %dd= image_tag image.url Ϧϩʔυ͢Δͱදࣔ͞Ε·͢
  47. controller ͱ view ͞Βͬͱ͓͞Β͍ routes ແ͍Α -> action ແ͍Α ->

    ςϯϓϨʔτແ͍Α -> ม਺Ξ αΠϯ͞Εͯͳ͍Α spec Λॻ͍͓ͯ͘͜ͱʹΑΓɺ࣮ߦΛ͢Δͨͼʹ΍Δ΂͖͜ͱΛ ڭ͑ͯ΋Β͍ͳ͕ΒҰาͮͭਐΊ·ͨ͠ɻ ͦͯ͠Τϥʔ͕ແ͘ͳͬͨΒ view Λ࣮૷͠·ͨ͠ɻ ࠓճ͸ view ͸ςετΛॻ͔ͣʹ໨Ͱ֬ೝ͠ͳ͕Β࣮૷͠·ͨ͠ɻ ͜͜ͰҰ୴ίϛοτ͓͖ͯ͠·͠ΐ͏ɻ
  48. image ొ࿥ը໘ جૅ͸આ໌ͨ͠ͷͰ͘͘͞͞ߦ͖·͢ spec/controllers/images_controller_spec.rb ʹొ࿥ը໘ͷ spec Λ௥Ճ͠·͢ɻ describe "#new" do

    it "assigns @image" do get :new expect(assigns(:image)).to_not be_nil end end spec ௨͢ͱ new ΞΫγϣϯ͕ແ͍ͱݴΘΕ·͢
  49. image ొ࿥ը໘ def new @image = Image.new end view ͕ແ͍ͱݴΘΕ·͢

  50. image ొ࿥ը໘ app/views/images/new.html.haml spec ͕௨ΔΑ͏ʹͳΔͷͰ࣮ࡍͷ view Λॻ͖·͢ = form_for @image

    do |f| = f.label :title = f.text_field :title = f.label :url = f.text_field :url = f.submit http://localhost:3000/images/new Λ։͍ͯΈ·͢
  51. image ొ࿥ը໘ REST తʹ new ͷ֓೦͸ແ͍ͷͰݴ༿Ͱઆ໌͢Δͷ΋೉͍͠ͷ Ͱઌʹ࣮૷ΛਐΊͯΈ·ͨ͠ɻ ຊ౰ʹλΠτϧͷ௨Γొ࿥ը໘Ͱ͢Ͷɻ ͜ͷը໘Ͱೖྗͨ͠΋ͷͰ࣮ࡍʹొ࿥Λ͢ΔͨΊͷॲཧΛݺͼ ग़͠·͢ɻ

    Ұ୴ίίͰίϛοτ͠·͠ΐ͏ɻ
  52. form_for ʹ͍ͭͯ = form_for @image do |f| form_for ͸Ҿ਺ʹ౉͞Ε͍ͯΔΦϒδΣΫτʹΑͬͯݺͼग़͠ઌΛม͑ͯ͘Ε·͢ɻ ྫ͑͹

    @image ͕ DB ʹطʹอଘ͞Ε͍ͯͨΒ PUT /images/:id(.:format) images#update ͕ݺ͹Εɺ·ͩอଘ͞Ε͍ͯͳ͍৔߹͸ POST /images(.:format) images#create ͕ݺ͹Ε·͢ɻ
  53. form_for ʹ͍ͭͯ ͭ·Γ Controller Ͱ @image = Image.new ͱ͖ͯͬ͠͞ͷ view

    Λදࣔͨ࣌͠͸৽نొ࿥ @image = Image.find(params[:id]) ͱ͖ͬ͞ͷ view Λදࣔͨ࣌͠͸طଘσʔλͷฤूʹͳΔΑ͏ ʹࣗಈతʹݺͼग़͠ઌΛม͑ͯ͘Ε·͢
  54. image ৽نొ࿥ ࣮ࡍʹσʔλΛొ࿥͢Δ෦෼Λ࡞੒͠·͠ΐ͏ spec/controllers/images_controller_spec.rb ʹ৽نొ࿥ͷ spec Λ௥Ճ͠·͢ɻ describe "#create" do

    it "create new image" do expect { post :create, image: { url: "http://example.com/", title: "test" } }.to change { Image.count }.from(0).to(1) end end ࠓճ͸࣮ࡍʹొ࿥͞Εͯݸ਺͕ 0 -> 1 ʹͳ͍ͬͯΔ͜ͱΛ֬ೝ͍ͯ͠·͢ spec ௨͢ͱ create ΞΫγϣϯ͕ແ͍ͱݴΘΕ·͢
  55. image ৽نొ࿥ def create Image.create(params.require(:image).permit(:url, :title)) end spec ௨͢ͱ view

    ͕ແ͍ͱݴΘΕ·͢
  56. image ৽نొ࿥ ొ࿥׬ྃը໘Λग़͢ͷͰ΋ྑ͍Ͱ͕͢ࠓճ͸ొ࿥͕੒ޭͨ͠Β ҰཡϖʔδʹભҠ͢ΔΑ͏ʹ͠·͠ΐ͏ def create Image.create(params.require(:image).permit(:url, :title)) redirect_to action:

    :index end http://localhost:3000/images/new Λ։͍ͯొ࿥Ͱ͖Δ͜ ͱΛ֬ೝͰ͖ͨΒίϛοτ͠·͠ΐ͏
  57. ొ࿥ը໘΁ͷϦϯΫ app/views/images/index.html.haml ʹԼهΛ௥Ճ͠·͢ɻ = link_to "ը૾Λ౤ߘ͢Δ", new_image_path ઌ΄Ͳ࣮ߦͨ͠ rake routes

    Ͱग़͖ͯͨ prefix ʹ _path Λ ͚ͭΔͱͦ͜΁ͷ path ʹͳΓ·͢ɻ ͳͷͰࠓճ͸ new_image_path ʹͳΓ·͢ɻ ·ͨίϛοτ͠·͢ɻ
  58. ը૾ݸผϖʔδ spec/controllers/images_controller_spec.rb describe "#show" do let(:image) { Image.create(url: "http://example.com/", title:

    "test") } it "assigns @image" do get :show, id: image.id expect(assigns(:image)).to eq image end end ͬ͘͞Γ rspec ࣮ߦͯ͠ action ແ͍ͱݴΘΕ·͢ɻ
  59. ը૾ݸผϖʔδ def show @image = Image.find(params[:id]) end spec ௨͢ͱ view

    ͕ແ͍ͱݴΘΕ·͢
  60. ը૾ݸผϖʔδ app/views/images/show.html.haml %h1= @image.title = image_tag @image.url app/views/images/index.html.haml ΋ͪΐͬͱม͑·͢ %dd

    = link_to image do = image_tag image.url ಈ࡞֬ೝ͕Ͱ͖ͨΒίϛοτ͠·͢ɻ
  61. ը૾࡟আ spec/controllers/images_controller_spec.rb describe "destroy" do let!(:image) { Image.create(url: "http://example.com/", title:

    "test") } it "destroy image" do expect { delete :destroy, id: image.id }.to change { Image.count }.from(1).to(0) end end ͬ͘͞Γ rspec ࣮ߦͯ͠ action ແ͍ͱݴΘΕ……
  62. ը૾࡟আ def destroy Image.find(params[:id]).destroy redirect_to action: :index end ࡟আޙ΋ index

    ΁ߦ͘Α͏ʹ͠·͢ spec ͕௨Δ͜ͱΛ֬ೝ͠·͢ɻ
  63. ը૾࡟আ app/views/images/show.html.haml ʹ࡟আ༻ͷϦϯΫΛ௥ Ճ͠·͢ %h1= @image.title = image_tag @image.url =

    link_to "࡟আ", @image, method: :delete ಈ࡞֬ೝ͠ίϛοτ͠·͢ɻ
  64. github ΁ push 1. New repository ΛΫϦοΫ͠৽͍͠ repository Λ࡞Γ·͢ 2.

    repository name ͸ ࣗ෼ͷ໊લ -rails-app ʹ͍ͯͩ͘͠͞ɻ 1. ԶͳΒ yoshiori-shoji-rails-app ޙ͸खॱ௨Γ git remote add origin git@xxxx:yoshiori/yoshiori-shoji-rails-app.git git push -u origin master Ͱ͢ɻʢϦϩʔυͯ͠Έ·͠ΐ͏ʣ
  65. github ͔Β clone ࣍ͷ։ൃ͸ PR ΛૹͬͯΈ·͢ 1. ྡͷਓͱϖΞΛ૊ΜͰ͍ͩ͘͞ 2. ͦͷਓͷΞϓϦΛ

    git clone ͠·͢ 3. bundle install & bin/rake db:migrate ͠·͢ ͊͞ɺࠓ͔Β͸ίνϥΛ࿔Γ·͢ɻ
  66. branch ࣍͸ը૾ʹίϝϯτΛ෇͚ΔػೳΛ࡞͍͖ͬͯ·͢ɻ ৽͍͠ػೳͰ͢ͷͰϒϥϯνΛ࡞ͬͯ࡞ۀ͠·͠ΐ͏ɻ $ git checkout -b add_images_comment $ git

    branch * add_images_comment master ࣗ෼͕ͲͷϒϥϯνʹډΔ͔֬ೝ͓͖ͯ͠·͠ΐ͏ ʢ͍͍ͩͨͷਓ͕λʔϛφϧʹ΋ΤσΟλʹ΋ग़ΔΑ͏ʹ͠·͢ʣ
  67. ίϝϯτ model ͷ࡞੒ ίϝϯτϞσϧΛ࡞੒͠·͢ɻ ࠓճ͸ը૾ʹԿݸ΋ίϝϯτΛ෇͚ΒΕΔΑ͏ʹ͢ΔͷͰҰରଟͷؔ࿈ͱͯ͠ද͠·͢ $ rails generate model comment

    image:references body:text class CreateComments < ActiveRecord::Migration def change create_table :comments do |t| t.references :image, index: true, foreign_key: true, null: false t.text :body, null: false t.timestamps null: false end end end body ΧϥϜΛ NOT_NULL ʹ͠·͢
  68. ίϝϯτ model ͷ࡞੒ ͬ͘͞ͱόϦσʔγϣϯΛ࣮૷͍͖ͯ͠·͠ΐ͏ require 'rails_helper' RSpec.describe Comment, type: :model

    do describe "validation" do let(:image) { Image.create(url: "http://example.com/", title: "test") } describe "body" do subject(:no_body_comment) { image.comments.build(body: nil) } it "require" do expect(no_body_comment).to_not be_valid expect(no_body_comment.errors[:body].size).to be 1 end end end end
  69. ίϝϯτ model ͷ࡞੒ DB ʹมߋ͕͋ͬͨͷͰ $ bin/rake db:migrate RAILS_ENV=test Λ࣮ߦ͔ͯ͠Β

    spec Λ࣮ߦ͢Δͱམͪ·͢ɻ Failure/Error: subject(:no_body_comment) { image.comments.build(body: nil) } NoMethodError: undefined method `comments' for #<Image:0x007fd9c9a2b020> # ./spec/models/comment_spec.rb:8:in `block (4 levels) in <t ͦ΋ͦ΋ image.comments.build ͱ͍͏ॻ͖ํ͸ԿͳͷͰ͠ΐ͏͔
  70. ϦϨʔγϣϯγοϓ ϞσϧͦΕͧΕʹؔ࿈৘ใΛ࣋ͨͤ·͢ class Image < ActiveRecord::Base validates :url, presence: true

    validates :title, presence: true + has_many :comments end class Comment < ActiveRecord::Base belongs_to :image end ͜ΕͰ Image ͱ Comment ΛҰରଟͱͯؔ͠࿈෇͚ΒΕ·ͨ͠ɻ
  71. ϦϨʔγϣϯγοϓ ͜ΕͰ image.comments.build ͱ࣮ߦ͢Δͱ image ʹؔ࿈ͮ ͍ͨ Comment Λ৽͘͠࡞੒͢Δ͜ͱ͕ग़དྷ·͢ɻ ࣮ࡍ͸Լهॲཧ͸΄΅ಉͩ͡ͱࢥͬͯ΋Βͬͯେৎ෉Ͱ͢

    > image.comments.build(body: "test") > Comment.new(image_id: image.id, body: "test")
  72. ίϝϯτ model ͷ࡞੒ ͯ͞ɺspec ʹ໭͖ͬͯ·͢ class Comment < ActiveRecord::Base validates

    :body, presence: true belongs_to :image end
  73. ίϝϯτ model ͷ࡞੒ ؔ࿈΋ςετ͓͖ͯ͠·͠ΐ͏ describe "image_id" do context "empty" do

    subject(:no_image_id_comment) { Comment.new(image_id: nil, body: "body") } it "invalid" do expect(no_image_id_comment).to_not be_valid expect(no_image_id_comment.errors[:image].size).to be 1 end end context "illegal id" do subject(:illegal_image_id_comment) { Comment.new(image_id: image.id + 1, body: "body") } it "invalid" do expect(illegal_image_id_comment).to_not be_valid expect(illegal_image_id_comment.errors[:image].size).to be 1 end end end
  74. ίϝϯτ model ͷ࡞੒ class Comment < ActiveRecord::Base validates :body, presence:

    true validates :image, presence: true belongs_to :image end spec ͕௨Δ͜ͱΛ֬ೝͯ͠ίϛοτ͠·͢ɻ
  75. ίϝϯτ౤ߘ spec/controllers/comments_controller_spec.rb require 'rails_helper' RSpec.describe CommentsController, type: :controller do let(:image)

    { Image.create(url: "http://example.com/", title: "text") } describe "#create" do it "create new comment" do expect { post :create, image_id: image.id, comment: { body: "ίϝϯτ" } }.to change { Comment.count }.from(0).to(1) end end end
  76. ίϝϯτ౤ߘ app/controllers/comments_controller.rb class CommentsController < ApplicationController end spec ࣮ߦ͢Δͱ·ͨ route

    ͕ઃఆ͞Ε͍ͯͳ͍ͱݴΘΕ· ͢ɻ
  77. ؔ࿈ resources ͷઃఆ ࠓճ͸ը૾ʹෳ਺ίϝϯτΛ෇͚ΒΕΔΑ͏ʹ͠·͢ɻ ͭ·Γɺը૾ 1 ʹ͍ͭͨίϝϯτҰཡΛද͢ path ͸ /images/1/comments

    ʹͳͬͯཉ͍͠Ͱ͢Ͷɻ
  78. ؔ࿈ resources ͷઃఆ ͜ΕΛ routes Ͱද͢ͱ resources :images do resources

    :comments end ͱද͠·͢ɻ rake routes ͯ͠ URI ͕௥Ճ͞Ε͍ͯΔ͜ͱΛ֬ೝͯ͠Έ· ͠ΐ͏
  79. ίϝϯτ౤ߘ ࣮ࡍͷ create ΞΫγϣϯΛ࣮૷͠·͢ class CommentsController < ApplicationController def create

    image = Image.find(params[:image_id]) image.comments.create(params.require(:comment).permit(:body)) redirect_to image_path(image) end end image Λऔಘͯͦ͠Εʹؔ࿈͢ΔίϝϯτΛ৽͘͠࡞੒͠·͢ɻ ׬ྃͨ͠Β image ͷݸผϖʔδʹભҠ͢ΔΑ͏ʹ͠·ͨ͠ɻ spec ͕௨Δ͜ͱΛ֬ೝ͠·͠ΐ͏
  80. ίϝϯτ౤ߘ ίϝϯτ౤ߘ͸ը૾ϖʔδ͔Β͍ͨ͠ͷͰը૾ϖʔδʹ form Λ௥Ճ͠·͢ app/views/images/show.html.haml %h2 ίϝϯτ %ul - @image.comments.each

    do |comment| %li = comment.body = form_for [@image, Comment.new] do |f| = f.text_field :body = f.submit form_for ΁ͷ౉͠ํ͕ͪΐͬͱบ͕͋ΔͷͰ஫ҙͰ͢
  81. ίϝϯτ౤ߘ $ bin/rake db:migrate ͨ͠ޙʹ http://localhost:3000/images/1 ʹΞΫηε͠ಈ࡞֬ೝΛͯ͠໰୊͕ͳ͔ͬͨΒίϛοτ͠· ͢ɻ

  82. Pull request Ͱ͸࣮૷ͨ͠ίϝϯτػೳΛϓϧϦΫΤετͱͯ͠ग़ͯ͠Έ·͢ɻ 1. ͖ͬ͞ͷ clone ͨ͠ϦϙδτϦͷϖʔδͰ fork ϘλϯΛԡ͢ 2.

    fork ͨ͠ url Ͱ git remote add mine #{url} ͢Δ 3. git push mine add_images_comment 4. fork ͨ͠ϖʔδΛ։͖ϓϧϦΫΤετϘλϯΛԡ͢ ऴΘͬͨΒٯʹࣗ෼ͷϦϙδτϦ΁͖ͨ PR ΛϚʔδ͠·͠ΐ͏ ࣗ෼ͷϓϩδΣΫτͷσΟϨΫτϦʹ໭Γ git pull origin master ͠ɺઌ΄ͲϚʔδͨ͠΋ͷ͕ϩʔΧϧʹ൓ө͞ΕͨͷΛ֬ೝ ͠·͠ΐ͏ɻ
  83. API Խ

  84. API Խ ࠓ͔Β json API Λ࡞͍͖ͬͯ·͠ΐ͏ɻ ·ͣ͸؆୯ʹ JSON ͷ spec

    Λॻ͚Δ rspec-json_matcher Λಋೖ͠·͢ɻ Gemfile ʹ gem "rspec-json_matcher", group: :test Λ଍͠ bundle install ͠·͢
  85. API Խ spec/spec_helper.rb ʹԼهΛ଍͠·͢ require "rspec/json_matcher" RSpec.configuration.include RSpec::JsonMatcher

  86. API Խ rake routes ͨ࣌͠ͷදࣔ images GET /images(.:format) images#index ͜͜ͷ

    URI Pattern ͷඞͣޙΖʹ෇͍͍ͯΔ (.:format) ͕ΩϞͰ͢ɻ Ͳ͏͍͏͜ͱ͔ͱ͍͏ͱ http://localhost:3000/images ʹΞΫηε͢Δͱී ௨ʹ html ͕ฦ͖ͬͯ·͕͢ɺhttp://localhost:3000/images.json ͱ֦ு ࢠ෩ʹ format Λࢦఆͯ͠ΞΫηε͢Δͱ json ͕ฦͬͯ͘ΔΑ͏ʹग़དྷ·͢3ɻ 3 format ͷࢦఆͷ࢓ํ͸ଞʹ΋͋Γ·͢
  87. API Խ Ͱ͸ͬͦ͘͞ spec Ͱ͢ɻࠓճ͸ json ͕ฦͬͯ͘Δ͜ͱ͕େࣄͳͷͰ request spec Λॻ͖·͢ɻ

    spec/requests/images_spec.rb Λ࡞Γ·͢ require "rails_helper" RSpec.describe Image, type: :request do let!(:image) { Image.create(url: "http://example.com/", title: "test") } describe "GET /images.json" do it "return json" do get "/images.json" expect(response.body).to be_json( images: [ id: image.id, title: "test", url: "http://example.com/", ], ) end end end
  88. API Խ spec Λ࣮ߦͯ͠ΈΔͱ·ͨςϯϓϨʔτ͕ແ͍ͱݴΘΕ·͕͢Α͘ݟΔͱ formats ͸ json ʹͳ͍ͬͯ·͢ɻࠓճ͸ rails ඪ४ͷ

    jbuilder Ͱॻ͍ͯ Έ·͢ app/views/images/index.json.jbuilder Λ࡞Γ·͢ json.images @images, :id, :title, :url spec Λ࣮ߦ͠௨Δ͜ͱΛ֬ೝͨ͠Βϒϥ΢βͰ΋ http://localhost: 3000/images.json Λ։͍ͯ֬ೝͯ͠Έ·͠ΐ͏ɻ ໰୊ͳ͚Ε͹ίϛοτ͠·͢ɻ
  89. API Խ ͜ͷ·· show ΋࣮૷ͯ͠Έ·͠ΐ͏ describe "GET /images/:id.json" do let!(:comment)

    { image.comments.create!(body: "test") } it "return json" do get "/images/#{image.id}.json" expect(response.body).to be_json( id: image.id, title: "test", url: "http://example.com/", comments: [ { id: comment.id, body: "test", }, ], ) end end
  90. API Խ app/views/images/show.json.jbuilder json.(@image, :id, :title, :url) json.comments @image.comments, :id,

    :body spec Λ࣮ߦ͠௨Δ͜ͱΛ֬ೝͨ͠Βϒϥ΢βͰ΋ http:// localhost:3000/images/1.json Λ։͍ͯ֬ೝͯ͠Έ·͠ΐ ͏ɻ ໰୊ͳ͚Ε͹ίϛοτ͠·͢ɻ
  91. API Խ ౤ߘ΋࡞͍͖ͬͯ·͠ΐ͏ describe "POST /images.json" do it "create images"

    do post "/images.json", image: { url: "http://example.com", title: "test" } expect(response.status).to be 201 end end spec Λ࣮ߦͯ͠Έ·͠ΐ͏ 302(ϦμΠϨΫτʣ͕ฦ͖ͬͯͯ͠·͍·͠ ͨͶɻ͔֬ϒϥ΢βͰͷಈ࡞͸౤ߘޙɺindex ϖʔδͰϦμΠϨΫτ͢ΔΑ ͏ʹ͍ͯ͠·ͨ͠ɻAPI ͷ࣌͸ͦΕ͸ෆཁͰ͢Ͷɻࠓճ͸ 201 ͚ͩฦͬͯ͘ ΔΑ͏ʹ͠·͢ɻ
  92. API Խ def create Image.create!(params.require(:image).permit(:title, :url)) respond_to do |format| format.html

    { redirect_to action: :index } format.json { head 201 } end end ͜ͷΑ͏ʹ format ʹΑͬͯॲཧΛ෼͚Δ͜ͱ͕ग़དྷ·͢ɻ
  93. API Խ ࣮ࡍʹίϚϯυϥΠϯ͔Β֬ೝͯ͠Έ·͠ΐ͏ $ curl -X POST -d "image[url]=http://example.com/&image[title]=test" http://localhost:3000/images.json

    rails ͷϩάΛݟΔͱ෼͔ΔͷͰ͕͢ Can't verify CSRF token authenticity CSRF token ͕ແ͍ͨΊ஄͔Ε͍ͯ·͢ɻ
  94. API Խ ຊདྷͳΒ͹ API ͸ Controller Λ෼͚ͯผͷೝূʢOAuth ౳ʣʹ͠· ͕͢ɺͪΐͬͱॏ͗͢ΔͷͰࠓճ͸ CSRF

    token ͷνΣοΫΛແޮʹ ͠·͢ɻʢઈରʹ࣮ࡍͷ։ൃͰߦͬͯ͸͍͚·ͤΜʣ app/conrtollers/apprication_controller.rb ͷԼهΛॻ͖׵͑· ͢ - protect_from_forgery with: :exception + protect_from_forgery with: :null_session ΋͏Ұ౓ίϚϯυϥΠϯ͔Βୟ͍ͯΈͯ໰୊ͳ͚Ε͹ίϛοτ͠·͢
  95. API Խ ίϝϯτ΋౤ߘͰ͖ΔΑ͏ʹ͠·͢ spec/requests/comments_spec.rb require "rails_helper" RSpec.describe Comment, type: :request

    do let(:image) { Image.create(url: "http://example.com/", title: "test") } describe "POST /images/:id/comments.json" do it "create comments" do post "/images/#{image.id}/comments.json", comment: { body: "test" } expect(response.status).to be 201 end end end
  96. API Խ app/conrtollers/comments_controller.rb class CommentsController < ApplicationController def create image

    = Image.find(params[:image_id]) image.comments.create(params.require(:comment).permit(:body)) respond_to do |format| format.html { redirect_to image_path(image) } format.json { head 201 } end end end spec ͕௨Δ͜ͱΛ֬ೝͨ͠Βίϛοτ͠·͠ΐ͏
  97. root ઃఆ root ΁ͷΞΫηε΋ը૾Ұཡʹ͠·͢ config/routes.rb ʹԼهΛ௥Ճ͠·͢ root "images#index" ๨Εͣʹίϛοτ͓͖ͯ͠·͠ΐ͏

  98. heroku ΁

  99. heroku ΁ Gemfile Λগ͠मਖ਼͠·͢ 1. sqlite3 Λ group :development, :test

    ϒϩοΫͷத΁Ҡ ಈ 2. ԼهΛ௥Ճ group :production do gem 'rails_12factor' gem 'pg' end
  100. heroku ΁ $ bundle install ͯ͠ίϛοτ $ heroku create $

    git push heroku master $ heroku run rake db:migrate $ heroku open ֬ೝͯ͠Έ·͠ΐ͏
  101. ͕࣌ؒ͋ͬͨΒௐ΂ͯΈΑ͏ʂ ࠓ೔͸࣌ؒͷؔ܎Ͱࡉ͔͘આ໌Ͱ͖ͳ͔ͬͨ΋ͷͰ͢ɻ 4 HTTP 4 REST 4 MVC 4 RDB

    4 OAuth 4 CSRF
  102. ࠷ޙʹ

  103. Rails νϡʔτϦΞϧ1 ΍Ζ͏ 1. ࠷ॳཧղͰ͖ͳͯ͘΋ 3 ճҐ΍Δͱ͍ͩͿ֮͑Δ 2. Web ։ൃͲ͏΍Μ͚ͩͬͬͯࢥͬͨ࣌ͱ͔ʹ͞Βͬͱ΍Δ

    ͱ·ͨࢥ͍ग़ͤΔ 1 http://railstutorial.jp/