プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • Ruby on Rails
  • 【Ruby on Rails】「Scaffolding(スキャフォールディング)」生成され…
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【Ruby on Rails】「Scaffolding(スキャフォールディング)」生成されたソースコード、jbuilder

06.23

  • miyabisan2
  • コメントを書く

この記事は8分で読めます

Ruby on Railsの「Scaffolding(スキャフォールディング)」という機能を利用すれば、アプリの雛形を自動生成できるとご紹介させて頂きました。

【Ruby on Rails】の「O/Rマッパー」である「ActiveRecord(アクティブレコード)」、Scaffoldingで雛形アプリ作成まで

一覧画面のソースコードを見てみる。

app/controllers/users_controller.rb

一覧画面に対応するアクションとしては、下記のindexアクションになります。

1
2
3
4
5
6
7
8
9
10
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]
 
  # GET /users
  # GET /users.json
  def index
    @users = User.all
  end
…
end

Usersモデルクラスのallメソッドを使って、インスタンス変数「@users」に格納しています。

app/views/users/index.html.erb

一覧に対応するビューとしては、こちらのビューになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<p id="notice"><%= notice %></p>
 
<h1>Users</h1>
 
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th colspan="3"></th>
    </tr>
  </thead>
 
  <tbody>
    <% @users.each do |user| %>
      <tr>
        <td><%= user.name %></td>
        <td><%= link_to 'Show', user %></td>
        <td><%= link_to 'Edit', edit_user_path(user) %></td>
        <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>
 
<br>
 
<%= link_to 'New User', new_user_path %>

<p id="notice"><%= notice %></p>

コントローラの処理結果を、ユーザーに通知したい場合に使われる変数です。

「<% @users.each do |user| %> …  <% end %>」のブロック

コントローラでモデルクラスから取り出した値をループで取り出しています。

「<%= link_to」から始まる内容

「link_to」はヘルパーメソッド(ビュー、コントローラで共通で呼び出せるメソッド)で、リンクであるaタグをHTMLに出力します。

1
link_to リンク名,リンク先

link_toメソッドで使える引数

引数 説明
リンク名 aタグで囲むテキスト名
リンク先 リンク先のURL

link_toメソッドで指定できるリンク先について

ルーティングに出力されていたPrefixに「_path」をつけた形式を指定すると、メソッドで指定できるリンク先のURLに変換されます。

ルーティング情報及び、Prefixは下記のコマンドで確認できます。

1
rails routes

表示画面

URLとしては、「http://IPアドレス:ポート番号/アクション名/ID」にアクセスした際に表示される画面になります。

まずは、コントローラの処理から見ていきましょう。

コントローラ(app/controllers/users_controller.rb)

まず、着目するのは、「before_action」から始まる下記の記述です。

1
2
3
4
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]
 …
end

結論から言えば、上記構文は、「show(表示画面)、edit(編集画面)、update(更新画面)、destroy(削除画面)」が呼び出された際に、事前処理として「set_userメソッド」を実行するという意味になります。

今回は、表示画面の解説になるので、「set_userメソッド」が呼び出されることになります。

詳しい構文の意味は、下記で解説しています。

before_actionメソッド

このメソッドは、「アクションを呼ぶ前に特定の処理をさせたい場合に定義するメソッド」になります。

構文

1
before_action メソッド名,条件ハッシュ

メソッドの引数の説明

メソッドの引数 説明
メソッド名 コントローラ内のメソッドをシンボルとして記述します。
条件ハッシュ 適用するアクションの条件をハッシュで記述します。

条件ハッシュの構文

1
(only/except):[アクションのシンボル1,アクションのシンボル2,…]

 only

指定したアクションのみに適用されます。

except

指定したアクション以外の全てのアクションに適用されます。

showアクション

表示画面は、下記の「showアクション」が対応しています。

1
2
3
4
  # GET /users/1
  # GET /users/1.json
  def show
  end

ただし、見て分かるとおりデフォルトでは何も中身が記述されていません。

では、画面に表示させる内容は、「set_userメソッド」で設定しているのです。

set_user(アクション名)メソッド

showアクションが呼ばれる前の事前処理になります。

1
2
3
4
5
6
7
  private
    # Use callbacks to share common setup or constraints between actions.
    def set_user
      @user = User.find(params[:id])
    end
    …
  end

ここでは、画面の表示させているURLのIDの値のデータを取得して、「@user変数」に代入しています。

1
User.find(params[:id])

「params[:id]」というのは、「http://192.168.10.5:3000/users/298486374」というURLで言えば、「298486374」の部分を取り出す構文(HTTPパラメータを取り出す構文)になります。

URLのどの部分を、取り出すかはルーティング情報に記載されています。

ビュー(app/views/users/show.html.erb)

1
2
3
4
5
6
7
8
9
<p id="notice"><%= notice %></p>
 
<p>
  <strong>Name:</strong>
  <%= @user.name %>
</p>
 
<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>

ビューの出力内容は、ほぼ一覧画面で出力している内容と同じです。

しいて言えば、画面表示に事前処理の「set_user(アクション名)メソッド」で代入した「@user」を使っていることでしょう。

登録画面

「Scaffolding」で自動生成された下記の「登録画面」のソースコードを見ていきます。

コントローラ(app/controllers/users_controller.rb)

登録画面のアクションとなるのは、「newアクション」になります。

1
2
3
4
5
6
7
8
9
class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]
 …
   # GET /users/new
  def new
    @user = User.new
  end
 …
end

@user = User.new

Userモデルクラスのnewメソッドを使うことで、インスタンスを生成して、「@userインスタンス変数」に格納しています。

ビュー(app/views/users/new.html.erb)

1
2
3
4
5
<h1>New User</h1>
 
<%= render 'form', user: @user %>
 
<%= link_to 'Back', users_path %>

<%= render 'form', user: @user %>

下記の構文を使っています。

1
<%= render 部分テンプレート名, キー1: 値1,キー2:値2 %>

部分テンプレート

ビューから切り出されたビューファイルのことです。

登録画面の入力フォームの部品内容を、各画面の共通処理として使いまわすことができるというメリットがあります。

登録画面で呼びされる部分テンプレートとしては、下記のパスにあるビューファイルになります。

app/views/users/_form.html.erb

また、第二引数で指定している「キー:値」のセットについては、「部分テンプレート(_form.html.erb)」の中に、アクションメソッドで用意された@user(Userモデルクラスのインスタンス)にuser変数でアクセスするということを意味しています。

<%= link_to 'Back', users_path %>

一覧画面へのリンクの作成をしています。

部分テンプレート(app/views/users/_form.html.erb)

部分テンプレートは、他の画面から共通処理として呼び出されるテンプレートになります。

new.html.erbから共通の部分テンプレートとして呼び出されているファイルになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<%= form_with(model: user, local: true) do |form| %>
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
 
      <ul>
      <% user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
 
  <div class="field">
    <%= form.label :name %>
    <%= form.text_area :name %>
  </div>
 
  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

form_withビューヘルパー(<%= form_with(model: user, local: true) do |form| %> ~ <% end %>)

引数の形式によって様々なformタグを出力するヘルパーメソッドです。

ヘルパーメソッドとは、ビューやコントローラで共通して呼び出されるメソッドのことです。

構文

1
2
3
<%= form_with(model: モデルクラスのインスタンス, local: 真偽値) do |form| %>
表示するフォームの内容
<% end %>

今回の場合はモデルクラスのインスタンスにuserが指定されているので、userモデルクラスの値をフォームの内容に使用することができます。

local:真偽値

Ajaxによるデータ更新を許可するかどうかの設定になります。

真偽値 説明
true Ajaxによるデータ更新を許可する必要がない場合に指定する。
false Ajaxによるデータ更新を許可する必要がある場合に指定する。

Ajaxについては、下記の記事で解説していますので、合わせてご覧下さい。

【JavaScript】Ajaxについて

画面に出力されるHTML

下記のHTMLが出力されます。

1
2
3
4
5
<form action="/users" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="&#x2713;" />
<input type="hidden" name="authenticity_token" value="Q7XS5s0p+B5fz9JkDZvOxWwzRtu5J5q3jBQXYaaQHOMLczS56uCvn1a97mU8gOv2l9PdP3jaK58ATFc+mvVVzg==" />
…
</form>

「<input type="hidden" name="authenticity_token"…」から始まるinputタグは、CSRF(クロスサイトリクエストフォージェリ)という不正アクセス対策に使用されるタグのことです。

labelビューヘルパー(<%= form.label :name %>)

構文

1
<%= form.label フィールド名 %>

フィールド名

モデルクラスのインスタンスのフィールド名のことです。

出力されるHTML

1
<label for="user_name">Name</label>

for属性で指定されている値は、その後に生成されるテキストエリア等の値と同じになります。

text_areaビューヘルパー(<%= form.text_area :name %>)

構文

1
<%= form.text_area 引数,属性名1:値1 %>

登録画面に、「textareaタグ」を出力します。任意ですが、出力されるtextareaタグに属性を増やしたい場合は、カンマ区切りで指定します。

出力されるHTML

1
2
<textarea name="user[name]" id="user_name">
</textarea>

name属性には、「オブジェクト名[カラム名]」のような配列が出力されています。

submitビューヘルパー(<%= form.submit %>)

構文

1
<%= form.submit %>

登録画面にサブミットボタンを出力します。

出力されるHTML

1
<input type="submit" name="commit" value="Create User" data-disable-with="Create User" />

data-disable-with属性は、二重クリック防止対策のための属性です。

データ登録

Scaffoldingで生成されたソースコードの登録画面のフォーム部分を見るとURLが「families(リソース名)」に対してPOSTしていることがわかります。

1
2
3
4
5
6
7
<form action="/families" accept-charset="UTF-8" method="post">
 <input type="hidden" name="authenticity_token" value="rI2sNF03GVrmh1i+zm3ZQNrJ7uIRAGVKEZNDgepKM0djHXNCNhV2aZbKzDxhxo/1H6zQXRD0oKLkqz3fPnvhaQ==" />
 ‥
  <div class="actions">
    <input type="submit" name="commit" value="Create Family" data-disable-with="Create Family" />
  </div>
</form>

コマンドでルーティングの情報をみてみるとfamiliesのPOSTはcreateメソッドを呼ぶようになっています。

コントローラのcreateメソッドは下記のようになっています。

1
2
3
4
5
6
7
8
9
10
11
12
13
  def create
    @family = Family.new(family_params)
 
    respond_to do |format|
      if @family.save
        format.html { redirect_to @family, notice: 'Family was successfully created.' }
        format.json { render :show, status: :created, location: @family }
      else
        format.html { render :new }
        format.json { render json: @family.errors, status: :unprocessable_entity }
      end
    end
  end

@family = Family.new(family_params)

famiily_paramsメソッドの戻り値を引数としてfamiliyモデルのインスタンスをnewメソッドで作成しています。

famiily_paramsメソッド

プライベートメソッドとして同じコントローラに下記のように定義されています。

1
2
3
    def family_params
      params.require(:family).permit(:name)
    end

Strong Parameters(ストロングパラメータ)

Strong Parameters(ストロングパラメータ)という構文で下記のように指定します。Strong Parametersは意図しないキーからパラメータは弾きエラーとするのでセキュリティ対策にもなります。Rails4から追加された仕組みです。(Rails3までは同じような仕組みとしてMassAssignmentが利用されていましたが脆弱性が見つかり、現在のところStrong Parameterが一般的に利用されています。)画面からサーバに送られてくるパラメータに制限をかけることができ不用意なデータがDBに登録できないようにするというセキュリティを向上させることができます。

1
params.require(モデル名).permit(キー1,キー2‥)

params

フォームから送信された値のことです。

require(:family)

引数には取得したいモデル名を指定します。そうすると入力フォームの値のハッシュ(キーと値の組み合わせ)になります。

permit

ハッシュから取得したい入力フォームの値のキーを指定します。

respond_toメソッド

ファイルのURLの末尾の拡張子によって処理を分ける場合に使用します。

RailsではURLに拡張子が何も指定されていない場合はHTMLと判断し、末尾に「.json」がついている場合はフォーマットがJSONと判断します。

1
2
3
4
respond_to do |format|
  format.html{URLの拡張子がHTMLの場合に実施する処理}
  format.json{URLの拡張子がJSONの場合に実施する処理}
end

@family.save

familyテーブルにデータを保存するメソッドです。保存に成功したらtrueを返し失敗したらfalseを返します。

redirect_toメソッド

リダイレクトを行います。後述するrenderと違ってURLを直接実行するので再度リクエストが発生することになります。

1
redirect_to リダイレクト先,出力メッセージ(flashメッセージ)

redirect_to @family

@familyというのは現在のオブジェクトのIDを示すので「families/新規登録ID」というURLにリダイレクトされることになります。ルーティング情報をみるとshowメソッドが呼ばれるので「show.html.erb」というビューに飛ぶことになります。

flashメッセージ

リダイレクトの際に、次のリクエストに対してデータを伝えるためにRailsが用意している仕組みで内部的にはセッションを利用して実現がされています。

上記コードのように「notice:」で指定した場合はnotice変数に格納されるので、ビュー側のHTMLでは「<%= notice %>」で参照できます。

render :show, status: :created, location: @family

テーブルにデータ登録が成功してかつURLの拡張子がJSONだった場合の処理です。redirect_toメソッドと違って2度リクエストが発生はしません。

render :show

views/falimlies/show.json.jbuilderをビューとして呼ぶ。

status: :created

Webサーバからの応答を示し、createdの場合はHTTPステータスコード201を返します。

location: @family

新しく登録されたデータのURLを示します。

views/falimlies/show.json.jbuilder

登録が成功して、URLの拡張子がJSONだった場合に呼ばれるソースになります。ソースの中には下記のような処理が記述されています。

1
json.partial! "families/family", family: @family

json.partial!ビューヘルパー

構文は下記のように記述して「JBuilder形式」の部分テンプレートを呼び出します。

1
json.partial! 部分テンプレート名,キー1:値1,キー2:値2‥

実際に呼び出すのは「views/families/_family.json.jbuilder」というファイルになります。

views/families/_family.json.jbuilder

下記のようなソースコードが記述されています。

1
2
json.extract! family, :id, :name, :created_at, :updated_at
json.url family_url(family, format: :json)

json.extract!ビューヘルパー

1
json.extract! モデルオブジェクト,カラム要素1,カラム要素2‥

モデルオブジェクトのキーと値のペアを出力します。上記例で言えば、familyテーブルのID、名前、登録日、更新日をJSON形式で出力することになります。

json.url family_url(family, format: :json)

URLを生成します。「families/ID.json」というURLを生成することになります。

render json: @family.errors, status: :unprocessable_entity

json: @family.errors

全てのエラーメッセージをJSON形式で返します。

status: :unprocessable_entity

HTTPステータスコード422を返し処理できなかったことを表します。

jbuilderとは?

Railsが標準で採用しているgemの一つでJSON形式のデータを出力するための簡単な記述方法を提供してくれるものです。

jbuilderの拡張子

拡張子を「.json.jbuilder」とするとそのビューファイル内でjbuilderが提供する記述を使うことができます。

jbuilderが提供する記述

json.partial!ビューヘルパー

jBuilder形式の部分テンプレートを呼び出すことができます。

json.extract!ビューヘルパー

モデルオブジェクトのカラム要素の値をJSON形式で出力します。

スポンサーリンク
  • 2018 06.23
  • miyabisan2
  • コメントを書く
  • Ruby on Rails
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2019 12.23

    【Docker】Ruby on Railsのコンテナを作成して起動するまで。

  2. 2020 03.28

    【Ruby on Rails】「Flashメッセージ」について

  3. 2020 01.06

    【Ruby on Rails】「devise」、「devise_invitable」について

  4. 2019 11.23

    【Ruby on Rails】アプリケーションサーバ「Puma」、「Unicorn」について

  5. 2020 12.26

    【Ruby on Rails】「serialize」や「store」について

  6. 2022 10.30

    【Rails】「rubocop」の導入、ソースレビューのポイントなど

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【JUnit】JUnitの基本や、使用できる「アノテー…

ナイロンの「ビジネスバッグ」にカビが生えた場合の対処法

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー