
Ruby on Rails 5アプリケーションプログラミング
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2017/04/14
- メディア: 大型本
- この商品を含むブログを見る
序文
「Ruby on Rails 5 アプリケーションプログラミング」学習5日目。
お金欲しい。
GitHub
客観的成果
- 第3章
- 3.3 詳細画面の作成(showアクション)
- 3.4 新規登録画面の作成(new/create アクション)
(学習時間:4時間)
コード実装部分
↓/app/controllers/cds_controller.rb
class CdsController < ApplicationController # before_action: アクションメソッドの前に実行するメソッドを指定する # このようなメソッドをフィルターという before_action :set_cd, only: [:show, :edit, :update, :destroy] # 省略 # GET /cds/new def new # 新規作成の場合は空のオブジェクトを渡す @cd = Cd.new end # 省略 # POST /cds # POST /cds.json # _form.html.erbのフォームから # /cdsにPOSTで入力データが渡されて発火する def create # 入力されたデータからオブジェクトを作成する # cd_paramsはメソッドではなくその返り値 # (cd_params()の括弧を省略した形) # インスタンス変数に代入しているのはエラー時の表示処理のため @cd = Cd.new(cd_params) # respond_toメソッドは指定されたフォーマットに応じて # 異なるテンプレートを呼び出す仕組み respond_to do |format| # 作成したオブジェクトを保存する # 成功したら if @cd.save # 指定されたフォーマットがHTMLなら # /{id値}にリダイレクトする # (@cdはオブジェクトのキー値と解釈される) # 現在のURLが/cdsであるから # /cds/{id値}にリダイレクトする # またオプションとしてデータを渡すことで # ビューテンプレートからローカル変数っぽく利用できる format.html { redirect_to @cd, notice: 'Cd was successfully created.' } # 指定されたフォーマットがJSONなら # show.json.builderで新規作成されたデータをJSON形式で出力する # status:はステータスコード # location:はリソース位置のURLを表す format.json { render :show, status: :created, location: @cd } # 失敗したら else # 指定されたフォーマットがHTMLなら # new.html.erbを再描画する format.html { render :new } # 指定されたフォーマットがJSONなら # エラー情報をJSON形式で書き出す # unprocessable_entityはデータを処理できなかったことを示す format.json { render json: @cd.errors, status: :unprocessable_entity } end end end # 省略 private # Use callbacks to share common setup or constraints between actions. # フィルターとしてアクションの前に呼び出されるメソッド def set_cd # params: URL経由で渡されたパラメータを取得するメソッド # ここではオブジェクトのキー値を取得している # 取得したキー値をもとにfindメソッドで特定のオブジェクトを取得する @cd = Cd.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. # フォームからの入力値を取得する def cd_params # 定型句として覚えろ params.require(:cd).permit(:jan, :title, :price, :artist, :released, :is_major) # 具体的な戻り値は以下のようなハッシュになる # { # "id"=>"51848956", # "jan"=>"4988002756452", # "title"=>"充分未来", # "price"=>2000, # "artist"=>"集団行動", # "released(1i)"=>"2018", # "released(2i)"=>"2", # "released(3i)"=>"7", # "is_major"=>"0", # } end end
↓/app/views/cds/show.html.erb
<p id="notice"><%= notice %></p> <p> <strong>Jan:</strong> <%= @cd.jan %> </p> <%# 省略 %> <%# edit_cd_pathはビューヘルパーで %> <%# 引数にidを渡すことで %> <%# /cds/:id/editというパスを返す %> <%# 引数のcdはやはりオブジェクトのキー値を表している %> <%# ↓出力されるHTML %> <%# <a href="/cds/51848956/edit">Edit</a> %> <%= link_to 'Edit', edit_cd_path(@cd) %> | <%# cds_pathもビューヘルパーで %> <%# /cdsというパスを返す %> <%# ↓出力されるHTML %> <%# <a href="/cds">Back</a> %> <%= link_to 'Back', cds_path %>
↓/app/views/cds/new.html.erb
<h1>New Cd</h1> <%# 部分テンプレートに@cdを渡してhtmlを描画する %> <%# _form.html.erbが部分テンプレートとして呼び出される %> <%= render 'form', cd: @cd %> <%# cds_pathはビューヘルパーで %> <%# /cdsというパスを返す %> <%# ↓出力されるHTML %> <%# <a href="/cds">Back</a> %> <%= link_to 'Back', cds_path %>
↓/app/views/cds/_form.html.erb
<%# ファイル名の先頭に_をつけることで部分テンプレートであることを宣言している %> <%# モデルに関連づいたフォームを生成する %> <%# 現在はform_forではなくform_withが推奨されている %> <%# do~endはrubyではブロックと呼ばれ、ひとかたまりの処理を表す %> <%# とりあえずdo~endは{}と同等のものとイメージしておく %> <%# JavaScriptの無名関数みたいなものだろうか %> <%# ブロックの概念はまだはっきりとはイメージできていないが %> <%# 引数と同じようにform_withメソッドに渡されていると考えるべきであるようだ %> <%# ↓出力されるHTML %> <%# <form action="/cds" accept-charset="UTF-8" method="post"> %> <%# <input name="utf8" type="hidden" value="✓" /> %> <%# <input type="hidden" name="authenticity_token" value="6ZdmXguc0SGCJOO/eP3p24QMOctlyOw2/BFBPaowAjNPtd9jP0hDxv/VL9p5J0bdgdNv4vGQdhufZ6e0vjKnQw==" /> %> <%# ブロック内の処理を反映する %> <%# </form> %> <%# <from>タグ以外に出力されているものは %> <%# IEの古いバージョンに対応させる文字コード関連の処理と %> <%# CSRF脆弱性対策っぽいです %> <%= form_with(model: cd, local: true) do |form| %> <%# ↓入力値検証で発生したエラー情報を表示するためのコード %> <% if cd.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(cd.errors.count, "error") %> prohibited this cd from being saved:</h2> <ul> <% cd.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <%# ↑ここまで %> <div class="field"> <%# .labelも.text_fieldも.number_fieldも %> <%# .date_selectも.check_boxも.submitも %> <%# 全部ビューヘルパー %> <%# formはFormBuilderオブジェクトで %> <%# 出力しようとしているフォームを意味する %> <%# :janは引数として渡したオブジェクトのjanプロパティを表しているようだ %> <%# (シンボルなので値そのものではない) %> <%= form.label :jan %> <%= form.text_field :jan, id: :cd_jan %> <%# ↓出力されるHTML %> <%# <label for="cd_jan">Jan</label> %> <%# <input id="cd_jan" type="text" name="cd[jan]" /> %> </div> <div class="field"> <%= form.label :title %> <%= form.text_field :title, id: :cd_title %> </div> <div class="field"> <%= form.label :price %> <%= form.number_field :price, id: :cd_price %> <%# ↓出力されるHTML %> <%# <label for="cd_price">Price</label> %> <%# <input id="cd_price" type="number" name="cd[price]" /> %> </div> <div class="field"> <%= form.label :artist %> <%= form.text_field :artist, id: :cd_artist %> </div> <div class="field"> <%= form.label :released %> <%= form.date_select :released, id: :cd_released %> <%# ↓出力されるHTML %> <%# <label for="cd_released">Released</label> %> <%# <select id="cd_released_1i" name="cd[released(1i)]"> %> <%# <option value="2013">2013</option> %> <%# <option value="2014">2014</option> %> <%# ︙ %> <%# <option value="2017">2017</option> %> <%# <option value="2018" selected="selected">2018</option> %> <%# <option value="2019">2019</option> %> <%# ︙ %> <%# <option value="2023">2023</option> %> <%# </select> %> <%# <select id="cd_released_2i" name="cd[released(2i)]"> %> <%# <option value="1">January</option> %> <%# <option value="2">February</option> %> <%# <option value="3" selected="selected">March</option> %> <%# <option value="4">April</option> %> <%# ︙ %> <%# <option value="12">December</option> %> <%# </select> %> <%# <select id="cd_released_3i" name="cd[released(3i)]"> %> <%# <option value="1">1</option> %> <%# <option value="2">2</option> %> <%# ︙ %> <%# <option value="27">27</option> %> <%# <option value="28" selected="selected">28</option> %> <%# <option value="29">29</option> %> <%# <option value="30">30</option> %> <%# <option value="31">31</option> %> <%# </select> %> </div> <div class="field"> <%= form.label :is_major %> <%= form.check_box :is_major, id: :cd_is_major %> <%# ↓出力されるHTML %> <%# <label for="cd_is_major">Is major</label> %> <%# <input name="cd[is_major]" type="hidden" value="0" /><input id="cd_is_major" type="checkbox" value="1" name="cd[is_major]" /> %> </div> <div class="actions"> <%= form.submit %> <%# ↓出力されるHTML %> <%# <input type="submit" name="commit" value="Create Cd" data-disable-with="Create Cd" /> %> </div> <%# 最終的には以下のようなハッシュデータがサーバーに送られる %> <%# cd: { %> <%# "id":51848956, %> <%# "jan":"4988002756452", %> <%# "title":"充分未来",%> <%# "price":2000, <%# "artist":"集団行動",%> <%# "released":"2018-02-07",%> <%# "is_major":true %> <%# } %> <% end %>
実行結果
感想
scaffoldで自動出力したソースコードにぽちぽちコメント付け。
一度、別の本でかんたんにさらったところだけど、より詳しく説明してくれてありがたい。
Rubyのブロックの概念の理解に手こずった。
JavaScriptの無名関数やコールバック関数のようなものとしてイメージするとしっくりいった気がする。
N予備校のスパルタのたまものである。
でもやっぱり手元にRubyのリファレンスも置いておきたいなぁ。
同じことをやるにも複数の記法が許容されてて、混乱しそうになっちゃう。
カロリーメイトください。
BGM
充分未来 / 集団行動 www.youtube.com