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

TechTrain RoRハンズオン

pokohide
April 05, 2019

TechTrain RoRハンズオン

pokohide

April 05, 2019
Tweet

More Decks by pokohide

Other Decks in Technology

Transcript

  1. Railsͷ։ൃ؀ڥΛߏங $ git clone https://github.com/pokohide/rails_app_for_tech_train.git $ cd rails_app_for_tech_train ## DockerͰRails؀ڥΛߏங

    $ docker-compose build ## σʔλϕʔε(PostgreSQL)Λ࡞੒ $ docker-compose run web rails db:create ## ্ཱͪ͛Δ $ docker-compose up ## GET http://localhost:3000/ ## Yay!! You’re on Rails!!
  2. ςʔϒϧઃܭ Questionςʔϒϧ DPOUFOU 4USJOH PSEFS@JOEFY *OUFHFS Choiceςʔϒϧ RVFTUJPO@JE *OUFHFS DPOUFOU

    4USJOH BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS ※ ޙͰઆ໌͠·͕͢ɺ͜Ε͸ϕετϓϥΫςΟεͰ͸͋Γ·ͤΜ 1 N
  3. QuestionϞσϧΛ࡞੒ (1) ## QuestionςʔϒϧΛ࡞੒͢Δ
 $ docker-compose run web rails g

    model Question content:string order_index:integer ## => # create db/migrate/20190330094200_create_questions.rb # create app/models/question.rb
  4. QuestionϞσϧΛ࡞੒ (1.1) # db/migrate/20190330094200_create_questions.rb class CreateQuestions < ActiveRecord::Migration[5.2] def change

    create_table :questions do |t| t.string :content t.integer :order_index t.timestamps end end end
  5. QuestionϞσϧΛ࡞੒ (1.2) # db/migrate/20190330094200_create_questions.rb class CreateQuestions < ActiveRecord::Migration[5.2] def change

    create_table :questions do |t| t.string :content t.integer :order_index, null: false, default: 0 t.timestamps end end end # order_indexʹNOT NULL੍໿ͱॳظ஋0Ληοτ
  6. QuestionϞσϧΛ࡞੒ (2) ## DBʹϚΠάϨʔγϣϯ $ docker-compose run web rails db:migrate

    ## QuestionϞσϧʹίϯιʔϧ͔ΒΞΫηεՄೳʹ $ docker-compose run web rails console > Question => Question(id: integer, content: string, order_index: integer, created_at: datetime, updated_at: datetime)
  7. ChoiceϞσϧΛ࡞੒ (1) ## ChoiceςʔϒϧΛ࡞੒͢Δ $ docker-compose run web rails g

    model Choice question:references content:string attr_1:integer attr_2:integer attr_3:integer attr_4:integer ## => # create db/migrate/20190330095049_create_choices.rb # create app/models/choice.rb
  8. QuestionϞσϧΛ࡞੒ (1.1) # db/migrate/20190330094200_create_questions.rb class CreateChoices < ActiveRecord::Migration[5.2] def change

    create_table :choices do |t| t.references :question, foreign_key: true t.string :content t.integer :attr_1 t.integer :attr_2 t.integer :attr_3 t.integer :attr_4 t.timestamps end end end
  9. QuestionϞσϧΛ࡞੒ (1.2) # db/migrate/20190330094200_create_questions.rb class CreateChoices < ActiveRecord::Migration[5.2] def change

    create_table :choices do |t| t.references :question, foreign_key: true t.string :content t.integer :attr_1, null: false, default: 0 t.integer :attr_2, null: false, default: 0 t.integer :attr_3, null: false, default: 0 t.integer :attr_4, null: false, default: 0 t.timestamps end end end # order_indexʹNOT NULL੍໿ͱॳظ஋0Ληοτ
  10. ChoiceϞσϧΛ࡞੒ (2) ## DBʹϚΠάϨʔγϣϯ $ docker-compose run web rails db:migrate

    ## ChoiceϞσϧʹίϯιʔϧ͔ΒΞΫηεՄೳʹ $ docker-compose run web rails console > Choice => Choice(id: integer, question_id: integer, content: string, attr_1: integer, attr_2: integer, attr_3: integer, attr_4: integer, created_at: datetime, updated_at: datetime) ## ·ͩQuestionϞσϧ͔ΒChoiceϞσϧʹ͸ΞΫηεͰ͖ͳ͍ > Question.new.choices =>NoMethodError: undefined method `choices' for #<Question: 0x000055d3f5a4c8c8>
  11. Question - Choice ͷϦϨʔγϣϯఆٛ # app/models/question.rb class Question < ApplicationRecord

    has_many :choices end # app/models/choice.rb class Choice < ApplicationRecord belongs_to :question end
  12. ςʔϒϧઃܭ Questionςʔϒϧ DPOUFOU 4USJOH PSEFS@JOEFY *OUFHFS Choiceςʔϒϧ RVFTUJPO@JE *OUFHFS DPOUFOU

    4USJOH BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS ※ ޙͰઆ໌͠·͕͢ɺ͜Ε͸ϕετϓϥΫςΟεͰ͸͋Γ·ͤΜ 1 N
  13. ॳظσʔλͷૠೖ ## db/fixtures/development/01_question.rb ## db/fixtures/development/02_choice.rb $ docker-compose run web rails

    db:seed_fu == Seed from /rails_app_for_tech_train/db/fixtures/development/01_question.rb - Question {:id=>1, :order_index=>1, :content=>"΋͋͠ͳ͕ͨεʔύʔώʔϩʔͷੈքʹ͍Δͱ ͨ͠৔߹ɺͲΜͳεΩϧ͕ཉ͍͠Ͱ͔͢ʁ"} - Question {:id=>2, :order_index=>2, :content=>”΋͋͠ͳ͕ͨεϚϗήʔϜͰετϨεൃࢄΛ͢ Δ৔߹ɺͲΜͳήʔϜΛબͼ·͔͢ʁ"} … == Seed from /rails_app_for_tech_train/db/fixtures/development/02_chocie.rb - Choice {:question_id=>1, :content=>"ࣗ༝ࣗࡏʹม਎Ͱ͖ΔεΩ ϧ", :attr_1=>1, :attr_2=>3, :attr_3=>5, :attr_4=>1} - Choice {:question_id=>1, :content=>"εϐʔυઓಆೳྗͱߴ͍ӡಈεΩϧ ", :attr_1=>4, :attr_2=>3, :attr_3=>0, :attr_4=>1} … ॳظσʔλ͸༻ҙͯ͋͠Γ·͢
  14. ೖΕͨσʔλΛ৮ͬͯ֬ೝʂ $ docker-compose run web rails console > Question.count =>

    5 > Question.first.content => “΋͋͠ͳ͕ͨεʔύʔώʔϩʔͷੈքʹ͍Δͱͨ͠৔߹ɺͲΜͳεΩϧ͕ཉ͍͠Ͱ͢ ͔ʁ” > Question.first.choices.pluck(:content) => ["ࣗ༝ࣗࡏʹม਎Ͱ͖ΔεΩϧ", "εϐʔυઓಆೳྗͱߴ͍ӡಈεΩϧ", "ے೑͕ൃ ୡͨ͠ݟࣄͳ೑ମͱɺఈ஌Εͳ͍ύϫʔ͕͋ΔεΩϧ", "͘͢͝ڧྗͳ೦ྗͱ৺ཧత߈ܸε Ωϧ"]
  15. ControllerΛ࡞੒ $ docker-compose run web rails g controller Questions index

    result create app/controllers/questions_controller.rb route get 'questions/index' get 'questions/result' create app/views/questions create app/views/questions/index.html.erb create app/views/questions/result.html.erb ࡞੒ͨ͠QuestionsController ͔Βఆٛͨ͠ϞσϧΛ৮Δ
  16. ϧʔςΟϯάΛఆٛ # config/routes.rb Rails.application.routes.draw do get 'questions/index' get 'questions/result' #

    For details on the DSL available within this file, see http:// guides.rubyonrails.org/routing.html end HTTPϦΫΤετͱControllerΛ݁Ϳ # config/routes.rb Rails.application.routes.draw do root to: 'questions#index' get :result, to: ‘questions#result’, as: :result end
  17. Controller͔Β࣭໰Λऔಘ # app/controllers/questions_controller.rb class QuestionsController < ApplicationController def index @questions

    = Question. all. order(:order_index) end def result end end ࣭໰(Question)Λશͯ(all)औಘͯ͠ɺ ॱ൪(order_index)Ͱฒͼସ͑Δ
  18. औಘ࣭ͨ͠໰ΛViewͰදࣔ͢Δ # app/views/question.html.erb <h1>Questions#index</h1> <p>Find me in app/views/questions/index.html.erb</p> <%- @questions.each

    do |question| %> <p><%= question.content %></p> <ul> <%- question.choices.each do |choice| %> <li><%= choice.content %></li> <%- end %> </ul> <%- end %>
  19. બΜͩબ୒ࢶΛαʔόʔʹૹΔ # app/views/question.html.erb <%= form_with url: result_path, local: true, method:

    :get do |f| %> <%- @questions.each do |question| %> <p><%= question.content %></p> <%- question.choices.each do |choice| %> <label> <%= f.radio_button "choices[#{question.id}]", choice.id %> <%= choice.content %> </label> <%- end %> <%- end %> <%= f.submit 'ճ౴' %> <% end %>
  20. બΜͩબ୒ࢶΛαʔόʔʹૹΔ ## αʔόʔͷϩά web_1 | Processing by QuestionsController#result as HTML

    web_1 | Parameters: {"utf8"=>"✓", "choices"=>{"1"=>"1", "2"=>"6", "3"=>"10", "4"=>"16", "5"=>"20"}, "commit"=>"ճ౴"} web_1 | Rendering questions/result.html.erb within layouts/ application web_1 | Rendered questions/result.html.erb within layouts/ application (0.6ms) web_1 | Completed 200 OK in 252ms (Views: 218.3ms | ActiveRecord: 0.0ms) ͪΌΜͱૹΒΕͯͦ͏ id=1ͷ࣭໰ͷબ୒ࢶ͸id=1 id=2ͷ࣭໰ͷબ୒ࢶ͸id=6 …
  21. બ୒ࢶ͔Β݁ՌΛܭࢉ ## αʔόʔͷϩά web_1 | Processing by QuestionsController#result as HTML

    web_1 | Parameters: {"utf8"=>"✓", "choices"=>{"1"=>"1", "2"=>"6", "3"=>"10", "4"=>"16", "5"=>"20"}, "commit"=>"ճ౴"} id=1, 6, 10, 16, 20ͷChoiceͷ attr_1, attr_2, attr_3, attr_4ͷ ͷ߹ܭ஋Λܭࢉ͢Δ Choiceςʔϒϧ RVFTUJPO@JE *OUFHFS DPOUFOU 4USJOH BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS
  22. બ୒ࢶ͔Β݁ՌΛܭࢉ # app/controllers/questions_controller.rb class QuestionsController < ApplicationController … def result

    choice_ids = params[:choices].values choices = Choice.where(id: choice_ids) @attr_1 = choices.sum(:attr_1) @attr_2 = choices.sum(:attr_2) @attr_3 = choices.sum(:attr_3) @attr_4 = choices.sum(:attr_4) end end GETύϥϝʔλ͔ΒChoiceͷIDҰཡΛऔಘ DB͔Βબ୒ࢶҰཡΛऔಘɺଐੑ஋Λܭࢉ
  23. ݁ՌΛදࣔͯ͠ΈΔ # app/views/result.html.erb <h1>Questions#result</h1> <p>Find me in app/views/questions/result.html.erb</p> <p>ଐੑ1ɿ <%=

    @attr_1 %></p> <p>ଐੑ2ɿ <%= @attr_2 %></p> <p>ଐੑ3ɿ <%= @attr_3 %></p> <p>ଐੑ4ɿ <%= @attr_4 %></p>
  24. ࣭໰Λม͑ͯΈΔ # db/fixtures/development/01_question.rb ##### Q.1 ##### Question.seed(:id) do |q| q.id

    = 1 q.order_index = 1 q.content = '΋͋͠ͳ͕ͨεʔύʔώʔϩʔͷੈքʹ͍Δͱͨ͠৔߹ɺͲΜͳεΩϧ͕ཉ͍͠Ͱ͔͢ʁ' end ##### Q.2 ##### Question.seed(:id) do |q| q.id = 2 q.order_index = 2 q.content = '΋͋͠ͳ͕ͨεϚϗήʔϜͰετϨεൃࢄΛ͢Δ৔߹ɺͲΜͳήʔϜΛબͼ·͔͢ʁ' end … $ dokcer-compose run web rails db:seed_fu
  25. બ୒ࢶ΍ଐੑΛม͑ͯΈΔ # db/fixtures/development/02_choice.rb ##### Q.1 ͷબ୒ࢶ ##### Choice.seed(:question_id, :content) do

    |a| a.question_id = 1 a.content = 'ࣗ༝ࣗࡏʹม਎Ͱ͖ΔεΩϧ' a.attr_1, a.attr_2, a.attr_3, a.attr_4 = 1, 3, 5, 1 end Choice.seed(:question_id, :content) do |a| a.question_id = 1 a.content = 'εϐʔυઓಆೳྗͱߴ͍ӡಈεΩϧ' a.attr_1, a.attr_2, a.attr_3, a.attr_4 = 4, 3, 0, 1 end … ࠓճ͸͋͑ͯattr_1, …ͱந৅తͳΧϥϜΛ࢖༻ ͍ͯ͠ΔͷͰԿͱղऍͯ͠΋OK
  26. ݁ՌΛදࣔͯ͠ΈΔ # app/views/result.html.erb <h1>Questions#result</h1> <p>Find me in app/views/questions/result.html.erb</p> <p>ͣΔݡ͍ɿ <%=

    @attr_1 %></p> <p>಄೴໌᏷ɿ <%= @attr_2 %></p> <p>୯७ɿ <%= @attr_3 %></p> <p>ߦ͖౰ͨΓ͹ͬͨΓɿ <%= @attr_4 %></p>
  27. BulmaΛಋೖ https:/ /bulma.io/ # app/views/layouts/application.html.erb <!DOCTYPE html> <html> <head> <title>RailsAppForTechTrain</title>

    <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks- track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= stylesheet_link_tag 'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/ css/bulma.min.css' %> </head> <body> <%= yield %> </body> </html>
  28. ࣭໰ϖʔδͷσβΠϯมߋ # app/views/questions/index.html.erb <section class="section"> <div class="container"> <%= form_with url:

    result_path, local: true, method: :get do |f| %> <%- @questions.each do |question| %> <h3 class="title is-3"><%= question.content %></h3> <%- question.choices.each do |choice| %> <label class="choice"> <%= f.radio_button "choices[#{question.id}]", choice.id %> <div class="notification"><%= choice.content %></div> </label> <%- end %> <%- end %> <%= f.submit 'ճ౴', class: "button is-primary" %> <% end %> </div> </section>
  29. ࣭໰ϖʔδͷσβΠϯมߋ # app/assets/stylesheets/questions.scss .choice { div { display: block; margin-bottom:

    1rem; } &:hover div { opacity: .8; cursor: pointer; } input[type="radio"] { display: none; &:checked + div { background-color: #00d1b2; color: #fff; } } }
  30. ݁ՌϖʔδͷσβΠϯมߋ # app/views/questions/result.html.erb <section class="section"> <div class="container"> <nav class="level"> <div

    class="level-item has-text-centered"> <div> <p class="heading">ͣΔݡ͍</p> <p class="title"><%= @attr_1 %> </div> </div> <div class="level-item has-text-centered"> <div> <p class="heading">಄೴໌᏷</p> <p class="title"><%= @attr_2 %> </div> </div> … </nav> </div> </section>
  31. ݁ՌʹԠͯ͡ग़͠෼͚ # app/controllers/questions_controller.rb class QuestionsController < ApplicationController … def result

    … if @attr_1 > 10 && @attr_4 < 10 @recommend = 'υϥΰϯΫΤετVIII ۭͱւͱେ஍ͱढΘΕ͠ඣ܅' elsif … @recommend = ‘τϧωίͷେ๯ݥ ෆࢥٞͷμϯδϣϯ' … @recommend = ‘υϥΫΤ2 Ϛϧλͷ;͗͠ͳ伴 ϧΧͷཱཱྀͪ’ end end end
  32. ݁ՌʹԠͯ͡ग़͠෼͚ # app/views/questions/result.html.erb <section class="section"> <div class=“container"> <nav class=“level”> …

    </nav> <article class="message is-primary"> <div class="message-body"> ͋ͳͨ͸ <span class="title is-4">ʮ<%= @recommend %>ʯ</span> ͕޷͖Ͱ͠ΐ͏ɻ </div> </article> </div> </section>
  33. ࠓճͷςʔϒϧઃܭ Questionςʔϒϧ DPOUFOU 4USJOH PSEFS@JOEFY *OUFHFS Choiceςʔϒϧ RVFTUJPO@JE *OUFHFS DPOUFOU

    4USJOH BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS ※ ͜Ε͸ϕετϓϥΫςΟεͰ͸ͳ͍ 1 N
  34. ͨͱ͑͹… Questionςʔϒϧ DPOUFOU 5FYU PSEFS@JOEFY *OUFHFS JNBHF 4USJOH Choiceςʔϒϧ RVFTUJPO@JE

    *OUFHFS DPOUFOU 4USJOH JNBHF 4USJOH ChoiceͱAttributeΛଟରଟͷؔ܎ʹ͢Δͱεέʔϥϒϧ 1 N Attributeςʔϒϧ OBNF 4USJOH Choice-Attribute ςʔϒϧ RVFTUJPO@JE *OUFHFS BUUS@JE *OUFHFS QPJOU *OUFHFS 1 N 1 N N M