Upgrade to Pro — share decks privately, control downloads, hide ads and more …

cookpad 2015 summer internship rails

cookpad 2015 summer internship rails

Yoshiori SHOJI

August 20, 2015
Tweet

More Decks by Yoshiori SHOJI

Other Decks in Technology

Transcript

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

    ͱ͍͏Θ͚ͰɺRails ๨Ε͔͚ͯΔͱࢥͬͨΒ Rails νϡʔ τϦΞϧ1 Λࢥ͍ग़͢ͱྑ͍Ͱ͠ΐ͏ɻ 1 http://railstutorial.jp/
  2. 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 Λೋճԡ͠·͢ɻ ͩΒʙ ͬͱΫοΫύουͷσʔλ͕औಘग़དྷ·ͨ͠ɻ
  3. HTTP(Hypertext Transfer Protocol) 4 1ߦ໨ʢϦΫΤετߦʣ 4 GETʢHTTP ϝιουʣ 4 /

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

    ऴྃ͸ Ctrl + ] Λ͓ͨ͠ޙʹ quit ͱίϚϯυΛଧͯ͹ग़དྷ· ͢ɻ
  5. REST ࢥ૝ʹ͍ͭͯ ྫ͑͹ /items/5 ͱ͍͏ URL ͕Ұͭͷ item Λද͍ͯͯ͠ 4

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

    HTTP ϝιουͷ GET ͰΞΫηε͢Δͱ item ͷू߹ʢҰ ཡʣ͕औಘͰ͖Δ 4 ྫ͑͹ /items/1, /items/2, /items/3, /items/4 …… ౳ 4 HTTP ϝιουͷ POST ͰΞΫηε͢Δͱ item ͷू߹ʹ৽͠ ͍ item Λ௥Ճ͢Δ ͱ͍͏;͏ʹͳΓ·͢
  7. Rails ͷ MVC ੌ͘୯७ʹॲཧΛॻ͘ͱ…… 4 controllerʢͱ routesʣ ͸Ϣʔβʔ͔ΒͷೖྗΛݩʹ model Λऔಘ͠ɺview

    ʹ౉͠·͢ 4 view ͸౉͞Εͨ model Λදࣔ͠·͢ ͱ͍͏ಈ͖Λ͠·͢ɻ୯७Ͱ͢Ͷɻ
  8. ͬͦ͘͞࡞Γ͸͡Ί·͠ΐ͏ $ rails new bokete -T Ͱ Rails ΞϓϦͷͻͳܗ͕ग़དྷ·͢ɻ $

    cd bokete ͯͦ͠ͷσΟϨΫτϦʹೖΓ·͢ɻ ࠓޙ͸͜ͷσΟϨΫτϦΛΞϓϦέʔγϣϯͷ HOME ͱͯ͠ ѻ͍جຊతʹ͸͜͜ͰίϚϯυΛ࣮ߦ͠·͢ɻ
  9. haml Խ Gemfile هࡌޙɺԼهΛ࣮ߦ͠·͢ $ bundle install ͜ΕͰϥΠϒϥϦͷΠϯετʔϧ͕ऴΘΓ·ͨ͠ɻ ࣍ʹςϯϓϨʔτΛ haml

    ʹ౷Ұ͠·͢ (ݩʑ͸ ERB ͩͬͨ΋ͷΛ haml ʹίϯόʔτ͠·͢) $ rails generate haml:application_layout convert $ rm app/views/layouts/application.html.erb
  10. RSpec ४උ $ rails generate rspec:install Ͱ rspec ͷॳظԽΛߦ͍·͢ $

    bundle exec rspec Ͱ GREEN Λ֬ೝͨ͠Β commit ͓͖ͯ͠·͠ΐ͏ $ git init $ git add . $ git commit -m "init"
  11. 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 ͷσʔλΛૢ࡞͢ΔϞσϧ͕࡞੒͞Ε·ͨ͠ɻ
  12. 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
  13. image Ϟσϧ࡞੒ DB ఆٛ ࣮ࡍʹσʔλϕʔεʹ migration ϑΝΠϧΛ൓ө͠·͢ɻ ࠓճ͸ςετ༻ͷ DB ʹ൓өͤ͞·͢

    $ bin/rake db:migrate RAILS_ENV=test rspec ࣮ߦͯ͠Έ·͠ΐ͏ $ bundle exec rspec pending ʹͳΓ·͢Ͷʢmodel Կ΋࣮૷͍ͯ͠ͳ͍ͷͰʣ
  14. 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 Λ࣮ߦ͢Δͱ੺͘ͳΓ·͢Ͷ
  15. 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"
  16. 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 ςετͷ಺༰ͷઆ໌͸ޙ΄Ͳ͠·͢ͷͰͱΓ࣮͋͑ͣߦͯ͠Έ·͠ΐ͏
  17. routes ͱ resources Failure/Error: get :index ActionController::UrlGenerationError: No route matches

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

    ͪΐͬͱલʹઆ໌ͨ͠ʮREST ࢥ૝ʹ͍ͭͯʯΛࢥ͍ग़͍ͯͩ͘͠͞ 4 ૢ࡞ͷର৅ͱͳΔϦιʔεΛ URL Ͱදݱ͢Δ 4 ͦΕʹ HTTP ͷϝιουΛ࢖ͬͯૢ࡞͢Δ routes ʹ images ͱ͍͏ϦιʔεΛૢ࡞͢Δͱઃఆͨ͠Θ͚Ͱ͢ɻ
  19. 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 ͕ݺ͹ΕΔͷ͔ग़͖ͯ·ͨ͠ɻ
  20. routes ͱ resources spec Ͱ֬ೝ͍ͯ͠Δͷ͸ GET ϝιουͰ index ʹΞΫηε͢Δͷ΋Ͱͨ͠ɻ ͜Ε͸

    URI Pattern ͱͯ͠͸ /images ʹͳΓ·͢ɻ ͜Ε͸ઌఔͷʮREST ࢥ૝ʹ͍ͭͯʯͰݴ͏ͱ 4 HTTP ϝιουͷ GET ͰΞΫηε͢Δͱ item ͷू߹ʢҰཡʣ͕औಘͰ͖ Δ 4 ྫ͑͹ /items/1, /items/2, /items/3, /items/4 …… ౳ ʹͳΓ·͢ɻ Ͱ͸ɺroute Λઃఆͨ͠ͷͰ rspec Λ࣮ߦͯ͠Έ·͠ΐ͏ɻ
  21. 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 Λ࣮ߦͯ͠Έ·͠ΐ͏ɻ
  22. 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 Λ࣮ߦͯ͠Έ·͠ΐ͏ɻ
  23. 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 ͷू߹ʣ͕ΞαΠ ϯ͞Ε͍ͯΔ͜ͱΛ֬ೝ͍ͯ͠·ͨ͠ɻ
  24. index view ࡞੒ haml ʹ͍ͭͯ ͬ͘͟Γ 4 html tag ߏ଄Λ

    YAML ͬΆ͘දͨ͠ςϯϓϨʔτΤϯδϯ 4 % Ͱී௨ʹλά -> %ul 4 - Ͱ ruby ͷߏจ -> - @images.each do |image| 4 = Ͱ ग़ྗ -> = image.title
  25. 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 Ϧϩʔυ͢Δͱදࣔ͞Ε·͢
  26. controller ͱ view ͞Βͬͱ͓͞Β͍ routes ແ͍Α -> action ແ͍Α ->

    ςϯϓϨʔτແ͍Α -> ม਺Ξ αΠϯ͞Εͯͳ͍Α spec Λॻ͍͓ͯ͘͜ͱʹΑΓɺ࣮ߦΛ͢Δͨͼʹ΍Δ΂͖͜ͱΛ ڭ͑ͯ΋Β͍ͳ͕ΒҰาͮͭਐΊ·ͨ͠ɻ ͦͯ͠Τϥʔ͕ແ͘ͳͬͨΒ view Λ࣮૷͠·ͨ͠ɻ ࠓճ͸ view ͸ςετΛॻ͔ͣʹ໨Ͱ֬ೝ͠ͳ͕Β࣮૷͠·ͨ͠ɻ ͜͜ͰҰ୴ίϛοτ͓͖ͯ͠·͠ΐ͏ɻ
  27. 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 ΞΫγϣϯ͕ແ͍ͱݴΘΕ·͢
  28. 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 Λ։͍ͯΈ·͢
  29. form_for ʹ͍ͭͯ = form_for @image do |f| form_for ͸Ҿ਺ʹ౉͞Ε͍ͯΔΦϒδΣΫτʹΑͬͯݺͼग़͠ઌΛม͑ͯ͘Ε·͢ɻ ྫ͑͹

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

    Λදࣔͨ࣌͠͸৽نొ࿥ @image = Image.find(params[:id]) ͱ͖ͬ͞ͷ view Λදࣔͨ࣌͠͸طଘσʔλͷฤूʹͳΔΑ͏ ʹࣗಈతʹݺͼग़͠ઌΛม͑ͯ͘Ε·͢
  31. 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 ΞΫγϣϯ͕ແ͍ͱݴΘΕ·͢
  32. ొ࿥ը໘΁ͷϦϯΫ app/views/images/index.html.haml ʹԼهΛ௥Ճ͠·͢ɻ = link_to "ը૾Λ౤ߘ͢Δ", new_image_path ઌ΄Ͳ࣮ߦͨ͠ rake routes

    Ͱग़͖ͯͨ prefix ʹ _path Λ ͚ͭΔͱͦ͜΁ͷ path ʹͳΓ·͢ɻ ͳͷͰࠓճ͸ new_image_path ʹͳΓ·͢ɻ ·ͨίϛοτ͠·͢ɻ
  33. ը૾ݸผϖʔδ 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 ແ͍ͱݴΘΕ·͢ɻ
  34. ը૾࡟আ 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 ແ͍ͱݴΘΕ……
  35. 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 Ͱ͢ɻʢϦϩʔυͯ͠Έ·͠ΐ͏ʣ
  36. github ͔Β clone ࣍ͷ։ൃ͸ PR ΛૹͬͯΈ·͢ 1. ྡͷਓͱϖΞΛ૊ΜͰ͍ͩ͘͞ 2. ͦͷਓͷΞϓϦΛ

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

    branch * add_images_comment master ࣗ෼͕ͲͷϒϥϯνʹډΔ͔֬ೝ͓͖ͯ͠·͠ΐ͏ ʢ͍͍ͩͨͷਓ͕λʔϛφϧʹ΋ΤσΟλʹ΋ग़ΔΑ͏ʹ͠·͢ʣ
  38. ίϝϯτ 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 ʹ͠·͢
  39. ίϝϯτ 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
  40. ίϝϯτ 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 ͱ͍͏ॻ͖ํ͸ԿͳͷͰ͠ΐ͏͔
  41. ϦϨʔγϣϯγοϓ ϞσϧͦΕͧΕʹؔ࿈৘ใΛ࣋ͨͤ·͢ 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 ΛҰରଟͱͯؔ͠࿈෇͚ΒΕ·ͨ͠ɻ
  42. ίϝϯτ 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
  43. ίϝϯτ model ͷ࡞੒ class Comment < ActiveRecord::Base validates :body, presence:

    true validates :image, presence: true belongs_to :image end spec ͕௨Δ͜ͱΛ֬ೝͯ͠ίϛοτ͠·͢ɻ
  44. ίϝϯτ౤ߘ 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
  45. ؔ࿈ resources ͷઃఆ ͜ΕΛ routes Ͱද͢ͱ resources :images do resources

    :comments end ͱද͠·͢ɻ rake routes ͯ͠ URI ͕௥Ճ͞Ε͍ͯΔ͜ͱΛ֬ೝͯ͠Έ· ͠ΐ͏
  46. ίϝϯτ౤ߘ ࣮ࡍͷ 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 ͕௨Δ͜ͱΛ֬ೝ͠·͠ΐ͏
  47. ίϝϯτ౤ߘ ίϝϯτ౤ߘ͸ը૾ϖʔδ͔Β͍ͨ͠ͷͰը૾ϖʔδʹ 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 ΁ͷ౉͠ํ͕ͪΐͬͱบ͕͋ΔͷͰ஫ҙͰ͢
  48. 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 ͠ɺઌ΄ͲϚʔδͨ͠΋ͷ͕ϩʔΧϧʹ൓ө͞ΕͨͷΛ֬ೝ ͠·͠ΐ͏ɻ
  49. API Խ ࠓ͔Β json API Λ࡞͍͖ͬͯ·͠ΐ͏ɻ ·ͣ͸؆୯ʹ JSON ͷ spec

    Λॻ͚Δ rspec-json_matcher Λಋೖ͠·͢ɻ Gemfile ʹ gem "rspec-json_matcher", group: :test Λ଍͠ bundle install ͠·͢
  50. 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 ͷࢦఆͷ࢓ํ͸ଞʹ΋͋Γ·͢
  51. 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
  52. API Խ spec Λ࣮ߦͯ͠ΈΔͱ·ͨςϯϓϨʔτ͕ແ͍ͱݴΘΕ·͕͢Α͘ݟΔͱ formats ͸ json ʹͳ͍ͬͯ·͢ɻࠓճ͸ rails ඪ४ͷ

    jbuilder Ͱॻ͍ͯ Έ·͢ app/views/images/index.json.jbuilder Λ࡞Γ·͢ json.images @images, :id, :title, :url spec Λ࣮ߦ͠௨Δ͜ͱΛ֬ೝͨ͠Βϒϥ΢βͰ΋ http://localhost: 3000/images.json Λ։͍ͯ֬ೝͯ͠Έ·͠ΐ͏ɻ ໰୊ͳ͚Ε͹ίϛοτ͠·͢ɻ
  53. 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
  54. 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 Λ։͍ͯ֬ೝͯ͠Έ·͠ΐ ͏ɻ ໰୊ͳ͚Ε͹ίϛοτ͠·͢ɻ
  55. 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 ͚ͩฦͬͯ͘ ΔΑ͏ʹ͠·͢ɻ
  56. 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 ʹΑͬͯॲཧΛ෼͚Δ͜ͱ͕ग़དྷ·͢ɻ
  57. 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 ͕ແ͍ͨΊ஄͔Ε͍ͯ·͢ɻ
  58. API Խ ຊདྷͳΒ͹ API ͸ Controller Λ෼͚ͯผͷೝূʢOAuth ౳ʣʹ͠· ͕͢ɺͪΐͬͱॏ͗͢ΔͷͰࠓճ͸ CSRF

    token ͷνΣοΫΛແޮʹ ͠·͢ɻʢઈରʹ࣮ࡍͷ։ൃͰߦͬͯ͸͍͚·ͤΜʣ app/conrtollers/apprication_controller.rb ͷԼهΛॻ͖׵͑· ͢ - protect_from_forgery with: :exception + protect_from_forgery with: :null_session ΋͏Ұ౓ίϚϯυϥΠϯ͔Βୟ͍ͯΈͯ໰୊ͳ͚Ε͹ίϛοτ͠·͢
  59. 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
  60. 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 ͕௨Δ͜ͱΛ֬ೝͨ͠Βίϛοτ͠·͠ΐ͏
  61. heroku ΁ Gemfile Λগ͠मਖ਼͠·͢ 1. sqlite3 Λ group :development, :test

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

    git push heroku master $ heroku run rake db:migrate $ heroku open ֬ೝͯ͠Έ·͠ΐ͏