Share
Embed
Transcript
71 slides
-
ࣗݾհ • Ά͜ͻͰʢञҪʣ • גࣜձࣾZIZAIɹWEBΤϯδχΞ • OthloTechͷදͬͯ·ͨ͠ • өըɾ༸υϥϚʢSUITS)ɾήʔϜ࣮گʢఋऀʣΛݟΔͷ͕͖ •
GitHubɿpokohideɹTwitterɿ@hyde141421356 -
גࣜձࣾZIZAI • 2015ʹ໊ݹͰੜ·Εͨϕϯνϟʔ • 2िؒલ·ͰʮגࣜձࣾDUOʯͰͨ͠ • ࠓͰࣾһ100໊Ҏ্ • ʮגࣜձࣾDUOɺຊΛͬͯ4ͷྺ࢙ʹນΛด͡·͢ɻʯ (https:/
/note.mu/daichiajt/n/n8cb50cf7fadd) -
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!! -
ςʔϒϧઃܭ Questionςʔϒϧ DPOUFOU 4USJOH PSEFS@JOEFY *OUFHFS Choiceςʔϒϧ RVFTUJPO@JE *OUFHFS DPOUFOU
4USJOH BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS ※ ޙͰઆ໌͠·͕͢ɺ͜ΕϕετϓϥΫςΟεͰ͋Γ·ͤΜ 1 N -
ςʔϒϧઃܭ - Πϝʔδ 1ͭͷ࣭(Question)ʹରͯ͠ɺ 4ͭͷબࢶ(Choice)͕ඥ͍͍ͯΔ ͜ͷબࢶΛબ͢Δͱ ଐੑ1 (attr_1) ͕ 4ϙΠϯτ
ଐੑ2 (attr_2) ͕ 3ϙΠϯτ ଐੑ3 (attr_3) ͕ 1ϙΠϯτ ଐੑ4 (attr_4) ͕ -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 -
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 -
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Ληοτ -
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) -
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 -
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 -
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Ληοτ -
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> -
Question - Choice ͷϦϨʔγϣϯఆٛ # app/models/question.rb class Question < ApplicationRecord
has_many :choices end # app/models/choice.rb class Choice < ApplicationRecord belongs_to :question end -
ςʔϒϧઃܭ Questionςʔϒϧ DPOUFOU 4USJOH PSEFS@JOEFY *OUFHFS Choiceςʔϒϧ RVFTUJPO@JE *OUFHFS DPOUFOU
4USJOH BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS ※ ޙͰઆ໌͠·͕͢ɺ͜ΕϕετϓϥΫςΟεͰ͋Γ·ͤΜ 1 N -
ॳظσʔλͷૠೖ ## 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} … ॳظσʔλ༻ҙͯ͋͠Γ·͢ -
ೖΕͨσʔλΛ৮ͬͯ֬ೝʂ $ docker-compose run web rails console > Question.count =>
5 > Question.first.content => “͋͠ͳ͕ͨεʔύʔώʔϩʔͷੈքʹ͍Δͱͨ͠߹ɺͲΜͳεΩϧ͕ཉ͍͠Ͱ͢ ͔ʁ” > Question.first.choices.pluck(:content) => ["ࣗ༝ࣗࡏʹมͰ͖ΔεΩϧ", "εϐʔυઓಆೳྗͱߴ͍ӡಈεΩϧ", "ے͕ൃ ୡͨ͠ݟࣄͳମͱɺఈΕͳ͍ύϫʔ͕͋ΔεΩϧ", "͘͢͝ڧྗͳ೦ྗͱ৺ཧత߈ܸε Ωϧ"] -
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 ͔Βఆٛͨ͠ϞσϧΛ৮Δ -
ϧʔςΟϯάΛఆٛ # 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 -
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)Ͱฒͼସ͑Δ -
औಘ࣭ͨ͠Λ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 %> -
બΜͩબࢶΛαʔόʔʹૹΔ # 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 %> -
બΜͩબࢶΛαʔόʔʹૹΔ ## αʔόʔͷϩά 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 … -
બࢶ͔Β݁ՌΛܭࢉ ## αʔόʔͷϩά 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 -
બࢶ͔Β݁ՌΛܭࢉ # 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͔ΒબࢶҰཡΛऔಘɺଐੑΛܭࢉ -
݁ՌΛදࣔͯ͠ΈΔ # 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> -
࣭Λม͑ͯΈΔ # 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 -
બࢶଐੑΛม͑ͯΈΔ # 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 -
݁ՌΛදࣔͯ͠ΈΔ # 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> -
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> -
࣭ϖʔδͷσβΠϯมߋ # 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> -
࣭ϖʔδͷσβΠϯมߋ # 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; } } } -
݁ՌϖʔδͷσβΠϯมߋ # 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> -
݁ՌʹԠͯ͡ग़͚͠ # 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 -
݁ՌʹԠͯ͡ग़͚͠ # 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> -
վળҊ • ճΛબ͠ͳͯ͘ʮճʯͰ͖ͯ͠·͏ • ݁ՌURL͕ृ͍ • ΦλΫλΠϓஅΈ͍ͨʹεϥΠυܗࣜͷճํ๏ • ࣭બࢶʹը૾Λ͑ΔΑ͏ʹͯ͠ΈΔ •
࣭݁ՌΛ໘ന͘ʂ͜ΜͳΜͰϋϚΕόζΔՄೳ ੑ͋Δ • ͔͍͍ͬ͜JSϥΠϒϥϦͰ݁ՌΛັͤΔ -
ࠓճͷςʔϒϧઃܭ Questionςʔϒϧ DPOUFOU 4USJOH PSEFS@JOEFY *OUFHFS Choiceςʔϒϧ RVFTUJPO@JE *OUFHFS DPOUFOU
4USJOH BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS BUUS@ *OUFHFS ※ ͜ΕϕετϓϥΫςΟεͰͳ͍ 1 N -
ͨͱ͑… 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