Slide 1

Slide 1 text

Rails Controller Fundamentals — ͱͬͱΔͼʔୈ31ճ 2018-09-24 — https://tottoruby.connpass.com/event/100646/ — @hamajyotan (SAKAGUCHI Takashi)

Slide 2

Slide 2 text

͖͞ʹ͓఻͑ — ͪΐͬͱͨ͠ Rails ίʔυΛಈ͔ͨ͠Γ͠·͢. ҎԼ ͷঢ়ଶ͕खݩʹ͋Δͱ, Ұॹʹࢼͨ͠ΓͰ͖·͢. — Ruby 2.5.1 , Rails 5.2.1 Ͱ࣮ࢪ͠·͕͢, ͦ͜·Ͱ ݫີʹ߹ΘͤΔඞཁ͸ͳ͍Ͱ͢. — gem sqlite3. (rails new Ͱ database Λࢦఆ͠ͳ͍ ͷͰطఆͰ࢖͍ͬͯΔ͚ͩͰ͋Γ, ߦؒಡΜͰผ DB ΛࢦఆͰ͖Ε͹ͦΕͰ OK Ͱ͢)

Slide 3

Slide 3 text

ࣗݾ঺հ — SAKAGUCHI Takashi — Office UMMM LLC — Ruby ͱ͔ Rails ͱ͔͕ͪΐͬͱͰ͖Δ͓͡͞ΜͰ͢

Slide 4

Slide 4 text

ࠓ೔࿩͢͜ͱ — scaffold Α͘ΈͯΈΑ͏ͱ͍͏݅ — resource routing ʹͩ͜ΘΖ͏ͱ͍͏݅ — template inheritance ศརͩΑͱ͍͏݅

Slide 5

Slide 5 text

scaffold Α͘ΈͯΈΑ͏ͱ͍͏݅

Slide 6

Slide 6 text

؆୯ͳΞϓϦΛ࡞Γͭͭ $ ruby -v ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] $ rails -v Rails 5.2.1 $ rails new example --skip-active-storage ग़ྗলུ... $ cd example/ $ ./bin/rails s ➡ http://localhost:3000

Slide 7

Slide 7 text

؆୯ͳΞϓϦΛ࡞Γͭͭ $ ./bin/rails scaffold message \ title body:text \ published:boolean $ ./bin/rails db:migrate ➡ http://localhost:3000/ messages

Slide 8

Slide 8 text

resource(s) ͳϧʔςΟϯά config/routes.rb Rails.application.routes.draw do resources :messages end $ rails routes Prefix Verb URI Pattern Controller#Action messages GET /messages(.:format) messages#index POST /messages(.:format) messages#create new_message GET /messages/new(.:format) messages#new edit_message GET /messages/:id/edit(.:format) messages#edit message GET /messages/:id(.:format) messages#show PATCH /messages/:id(.:format) messages#update PUT /messages/:id(.:format) messages#update DELETE /messages/:id(.:format) messages#destroy

Slide 9

Slide 9 text

ΞΫγϣϯͱͦͷҙຯ Action ҙຯ index Ұཡදࣔ(ը໘) create ৽ن࡞੒ new ৽ن࡞੒(ը໘) edit ฤू(ը໘) show ৄࡉදࣔ(ը໘) update ߋ৽ destroy ࡟আ

Slide 10

Slide 10 text

html ౎߹ͷ new/edit ͸͜ͷ͍͞ஔ͍ͱ͘ Resource HTTP Method Action ҙຯ /messages GET index Ұཡදࣔ(ը໘) /messages POST create ৽ن࡞੒ /message/:id GET show ৄࡉදࣔ(ը໘) /message/:id PATCH/PUT update ߋ৽ /message/:id DELETE destroy ࡟আ

Slide 11

Slide 11 text

HTTP ͷϝιου HTTP Method /messages /message/:id GET index show PUT/PATCH - update DELETE - destroy POST create -

Slide 12

Slide 12 text

HTTP ͷϝιου HTTP Method ҙਤͳͲ ҆શ ႈ౳ GET Ϧιʔεͷऔಘ ! ! PUT/PATCH Ϧιʔεͷ഑ஔ !❓ DELETE Ϧιʔεͷ࡟আ !❓ POST Ϧιʔεͷੜ੒

Slide 13

Slide 13 text

GET — Ϧιʔεͷऔಘ. ৗʹ҆શͰႈ౳. — scaffold ͷ࣮૷ͩͱ, ίϨΫγϣϯ΁ͷ GET ͸ৗʹ 200 Ͱϝϯόʔ΁ͷ GET ͸ͳ͍৔߹ 404 Λฦ͢. def index @messages = Message.all end def show end

Slide 14

Slide 14 text

PUT/PATCH — Ϧιʔεͷ഑ஔ. — scaffold ͷ࣮૷ͷ৔߹ଘࡏ͠ͳ͍৔߹͸ 404 Λฦ͢ ͕, ఆ͔ٛΒ͢Ε͹ ID Λ໌ࣔͨ͠ merge (insert or update) ͱͨ͠ํ͕ద౰͔΋. def update respond_to do |format| if @message.update(message_params) format.html { redirect_to @message, notice: 'Message was successfully updated.' } format.json { render :show, status: :ok, location: @message } else format.html { render :edit } format.json { render json: @message.errors, status: :unprocessable_entity } end end end

Slide 15

Slide 15 text

DELETE — Ϧιʔεͷ࡟আ. — scaffold ͷ࣮૷ͷ৔߹ଘࡏ͠ͳ͍৔߹͸ 404 Λฦ͢ ͕, ఆ͔ٛΒ͢Ε͹ଘࡏ͠ͳ͍৔߹͸Կ΋͠ͳ͍ͷ͕ ద౰͔΋. def destroy @message.destroy respond_to do |format| format.html { redirect_to messages_url, notice: 'Message was successfully destroyed.' } format.json { head :no_content } end end

Slide 16

Slide 16 text

POST — Ϧιʔεͷੜ੒ — ʮੜ੒ʯͱ͍ͯ͠Δͷ͸ίϨΫγϣϯϦιʔεʹର ͢Δૢ࡞Ͱ͋ΔͨΊ. def create @message = Message.new(message_params) respond_to do |format| if @message.save format.html { redirect_to @message, notice: 'Message was successfully created.' } format.json { render :show, status: :created, location: @message } else format.html { render :new } format.json { render json: @message.errors, status: :unprocessable_entity } end end end

Slide 17

Slide 17 text

60ߦ͢͜͠ class MessagesController < ApplicationController before_action :set_message, only: [:show, :edit, :update, :destroy] def index @messages = Message.all end def show; end def new @message = Message.new end def edit; end def create @message = Message.new(message_params) respond_to do |format| if @message.save format.html { redirect_to @message, notice: 'Message was successfully created.' } format.json { render :show, status: :created, location: @message } else format.html { render :new } format.json { render json: @message.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @message.update(message_params) format.html { redirect_to @message, notice: 'Message was successfully updated.' } format.json { render :show, status: :ok, location: @message } else format.html { render :edit } format.json { render json: @message.errors, status: :unprocessable_entity } end end end def destroy @message.destroy respond_to do |format| format.html { redirect_to messages_url, notice: 'Message was successfully destroyed.' } format.json { head :no_content } end end private def set_message @message = Message.find(params[:id]) end def message_params params.require(:message).permit(:title, :body, :published) end end

Slide 18

Slide 18 text

resource routing ʹͩ͜ΘΖ͏ͱ͍͏݅

Slide 19

Slide 19 text

ϝοηʔδʹ͓ؾʹೖΓΛ͚͍ͭͨ — ͬͯཁ݅Λߟ͑ͯΈΔ. — ಛఆͷϝοηʔδʹର͓ͯ͠ؾʹೖΓʹͨ͠ΓͦΕ Λ֎ͨ͠ΓͰ͖Δ — ࠓճ͸ʮ୭͕ʯ͓ؾʹೖΓΛ͚ͭΔͷ͔? ͱ͍͏৘ใ ͸αϘΔ — ຊ࣭Ͱͳ͍ͷͰ, ؆୯ʹ favorited:boolean ͷ ϑϥάΛ Message Ϟσϧʹ͚ͭΔ͚ͩʹͯ͠Δ.

Slide 20

Slide 20 text

favorited ϑϥάΛ༻ҙ͢Δ $ ./bin/rails g migration AddFavoritedToMessages favorited:boolean $ ./bin/rails db:migrate

Slide 21

Slide 21 text

ͲͷΑ͏ͳΞΫγϣϯΛ४උ͢΂͖͔? resources :messages do post :add_favorite, on: :member post :remove_favorite, on: :member end $ ./bin/rails routes Prefix Verb URI Pattern Controller#Action add_favorite_message POST /messages/:id/add_favorite(.:format) messages#add_favorite remove_favorite_message POST /messages/:id/remove_favorite(.:format) messages#remove_favorite ... class MessagesController < ApplicationController def add_favorite end def remove_favorite end ... ➡ (´ɾТɾ`)…

Slide 22

Slide 22 text

ͲͷΑ͏ͳΞΫγϣϯΛ४උ͢΂͖͔? resources :messages do put :favorite, on: :member delete :favorite, on: :member end $ ./bin/rails routes Prefix Verb URI Pattern Controller#Action favorite_message PUT /messages/:id/favorite(.:format) messages#favorite DELETE /messages/:id/favorite(.:format) messages#favorite ... class MessagesController < ApplicationController def favorite # favorite & unfavorite ? end ... ➡ (´ɾТɾ`)……

Slide 23

Slide 23 text

ͲͷΑ͏ͳΞΫγϣϯΛ४උ͢΂͖͔? resources :messages do put :favorite, on: :member, action: 'add_favorite' delete :favorite, on: :member, action: 'remove_favorite' end $ ./bin/rails routes Prefix Verb URI Pattern Controller#Action favorite_message PUT /messages/:id/favorite(.:format) messages#add_favorite DELETE /messages/:id/favorite(.:format) messages#remove_favorite ... class MessagesController < ApplicationController def add_favorite end def remote_favorite end ... ➡ (´ɾТɾ`)………

Slide 24

Slide 24 text

ϧʔςΟϯάͷઃܭΨΠυϥΠϯ — resource(s) Ͱఏڙ͞ΕΔΞΫγϣϯҎ֎Λආ͚Δ — index, show, new, create, edit, update, destroy ͷΈ — config/routes.rb Ͱ get ͱ͔ post ͱ͔Λͳ Δ΂͘࢖Θͳ͍.

Slide 25

Slide 25 text

ϧʔςΟϯάͷઃܭΨΠυϥΠϯ — ࣮ݱ͢Δ͜ͱ͔Β໊ࢺΛ୳͠, ੵۃతʹαϒϦιʔε ͱͯ͠σβΠϯ͢Δ — /messages/:message_id/favorite

Slide 26

Slide 26 text

ϧʔςΟϯάͷઃܭΨΠυϥΠϯ — ࠓճͷྫͰ͸ /messages/:message_id/ favorite ʹରͯ͠ PUT/DELETE Ͱ࣮ݱ — DELETE ͔ͩΒͱݴͬͯ, ࣮ࡍʹ DB ্ͰσʔλΛ ࡟আ͢Δඞཁ͸ͳ͍. — URI ͷϦιʔεʹର͠, DB ͰͷӬଓԽํ๏͸શ ͘ผͷ࿩. — DBߏ੒ม͑Δͨͼʹ URIߏ੒ม͑ͳ͍Ͱ͠ΐ?

Slide 27

Slide 27 text

࠶ߟ - ϧʔςΟϯά resources :messages do resource :favorite, only: %i[update destroy], module: 'messages' end $ ./bin/rails routes Prefix Verb URI Pattern Controller#Action message_favorite PATCH /messages/:message_id/favorite(.:format) messages/favorites#update PUT /messages/:message_id/favorite(.:format) messages/favorites#update DELETE /messages/:message_id/favorite(.:format) messages/favorites#destroy ...

Slide 28

Slide 28 text

࠶ߟ - ίϯτϩʔϥ # app/controllers/messages/favorites_controller.rb class < Messages::FavoritesController before_action :set_message def update respond_to do |format| if @message.update(favorited: true) format.html { redirect_to @message, notice: 'Favorited.' } else format.html { redirect_to @message, alert: 'Favorite failed.' } end end end def destroy respond_to do |format| if @message.update(favorited: false) format.html { redirect_to @message, notice: 'Unfavorited.' } else format.html { redirect_to @message, alert: 'Unfavorite failed.' } end end end private def set_message @message = Message.find(params[:message_id]) end end # (json লུ.)

Slide 29

Slide 29 text

template inheritance ศརͩΑͱ͍͏݅

Slide 30

Slide 30 text

template inheritance #ͱ͸ — Ϗϡʔ͸ͲͷσΟϨΫτϦ/ϑΝΠϧΛ୳ࡧ͢Δ? — app/views/ίϯτϩʔϥ໊/ΞΫγϣϯ໊.֦ுࢠ Έ͍ͨͳͱ͜Ζ? — ➡ ͍͍ͩͨ͋ͬͯΔ͚Ͳ΋͏ͻͱ͍͖ — ➡ ❓

Slide 31

Slide 31 text

template inheritance #ͱ͸ — Ϗϡʔ͸ͲͷσΟϨΫτϦ/ϑΝΠϧΛ୳ࡧ͢Δ? — app/views/ίϯτϩʔϥ໊/ΞΫγϣϯ໊.֦ுࢠ Έ͍ͨͳͱ͜Ζ? — ➡ ͍͍ͩͨ͋ͬͯΔ͚Ͳ΋͏ͻͱ͍͖ — ➡ ίϯτϩʔϥͷܧঝπϦʔ͕ώϯτʹͳ͍ͬͯΔ

Slide 32

Slide 32 text

view template ͷ୳ࡧॱং — ίϯτϩʔϥͷܧঝπϦʔ — MessagesController — < ApplicationController — ➡ ҎԼͷॱʹ୳ࡧ͞ΕΔ 1. app/views/messages/* 2. app/views/application/*

Slide 33

Slide 33 text

view template ͷ୳ࡧॱং — ྫ͑͹ Messages ͷαϒΫϥεͷ Foos Λ࡞ͬͨΒ — FoosController < MessagesController — ➡ ҎԼͷॱʹ୳ࡧ͞ΕΔ 1. app/views/foos/* 2. app/views/messages/* 3. app/views/application/*

Slide 34

Slide 34 text

ͪΐͬͱͨΊͦ͏ $ mkdir app/views/application $ mv app/views/messages/index.html.erb app/views/application/ ➡ ৔ॴҠͯ͠΋ಈ͘. $ cp app/views/application/index.html.erb app/views/messages/index.html.erb $ echo '

΄͛

' >> app/views/messages/index.html.erb ➡ messages/ ͕༏ઌ.

Slide 35

Slide 35 text

ΈΜͳ ApplicationController Λܧঝͯ͠Δͱ͍͏͜ͱ͸ — app/views/application/ ͸ڞ௨ϏϡʔςϯϓϨ ʔτஔ͖৔ʹ࢖͑Δ. — ͔͠΋, ৔߹ʹΑͬͯ͸֤ʑͷίϯτϩʔϥͰ্ॻ͖ Ͱ͖Δ. — ͜Ε஌Βͣʹ app/views/shared/* ͱ͔࡞ΔΑΓ Rails way ͔ͱ.

Slide 36

Slide 36 text

ͨͱ͑͹͜ΜͳϧʔςΟϯά — /messages - ϝοηʔδҰཡ — ͜Εʹରͯ͠ɺ /messages/draft ͱ͍͏ URL Λ४ උ͢Δ — جຊతʹ͸ /messages ͱಉ͡. — ͨͩ͠, published ͕ false ͷσʔλͰϑΟϧλ ͞Εͨঢ়ଶͱ͢Δ.

Slide 37

Slide 37 text

/messages/draft Λͭ͘Δ - 1/4 app/controllers/messages_controller.rb def index - @messages = Message.all + @messages = message_scope end private + def message_scope + Message.all + end + def set_message

Slide 38

Slide 38 text

/messages/draft Λͭ͘Δ - 2/4 app/controllers/messages/ drafts_controller.rb class Messages::DraftsController < MessagesController private def message_scope Message.where(published: false) end end

Slide 39

Slide 39 text

/messages/draft Λͭ͘Δ - 3/4 config/routes.rb Rails.application.routes.draw do + namespace :messages do + resources :drafts, only: %i[index] + end resources :messages end

Slide 40

Slide 40 text

/messages/draft Λͭ͘Δ - 4/4 config/routes.rb Rails.application.routes.draw do namespace :messages do - resources :drafts, only: %i[index] + resources :drafts, only: %i[index], path: 'draft' end resources :messages end ➡ Ҏ্ ❗ Ϗϡʔͷमਖ਼ͳͲ͸ͳ͠

Slide 41

Slide 41 text

·ͱΊ — scaffold ͷు͘ίϯτϩʔϥ͸ྑ͍ίʔυ. — routes ʹ͸ͳΔ΂͘ resource(s) ͚ͩΛهड़. — URIͰσβΠϯ͢ΔϦιʔεͱ DBӬଓԽ͸ผͷ࿩. — template inheritance Λ͏·͘࢖͓͏. — ڞ௨ͷςϯϓϨʔτ͸ app/views/application/ σΟϨΫτϦ