ぺーぺーSEのブログ

備忘録・メモ用サイト。

スキャフォールディング(Scaffolding)機能について

環境構築は以下で。

blog.pepese.com

また、上記で説明した内容は以降では説明しない。

Railsの「rails generate」コマンドにscaffoldというGENERATORがある。
これは、アプリケーションの基本的な機能の一覧(index)、詳細(show)、新規作成(new/create)、編集(edit/update)、削除(destroy)を行うために必要なコントローラ、モデル、ビュー等をまとめて生成するGENERATORである。

スキャフォールディングの手順

以下の順でコマンドを実行していくと、とりあえず動くアプリができる。

  1. cd C:\rubyWorkspace
    • ここをワークディレクトリとする
  2. rails new scaffolding
    • scaffoldingというアプリの作成
  3. cd scaffolding
    • アプリのディレクトリへ移動
  4. rails generate scaffold user no:string name:string age:integer birthday:date active:boolean
    • 「番号(no)」「名前(name)」「年齢(age)」「誕生日(birthday)」「アクティブユーザか否か(active)」の情報をCRUDするアプリを作成する
    • 失敗したら「rails destroy scaffold user」コマンドで削除可能
  5. rake db:migrate
    • テーブル作成
    • 失敗したら「rake db:rollback」コマンドで1つ前の状態へ戻すことが可能
    • 最初の状態に戻したい場合は「rake db:migrate VERSION=0
  6. rake db:fixtures:load FIXTURES=users
    • テーブルへテストデータを下敷き
  7. rails server
    • Webサーバ起動

以下へブラウザでアクセスするとアプリの起動が確認できる。
http://localhost:3000/users

説明

rails generate scaffold」コマンドで作成されたファイルは以下。

C:\RUBYWORKSPACE\SCAFFOLDING
├─app
│  ├─assets
│  │  ├─javascripts
│  │  │      users.js.coffee
│  │  │
│  │  └─stylesheets
│  │          scaffolds.css.scss
│  │          users.css.scss
│  │
│  ├─controllers
│  │      users_controller.rb
│  │
│  ├─helpers
│  │      application_helper.rb
│  │      users_helper.rb
│  │
│  ├─models
│  │      user.rb
│  │
│  └─views
│      ├─layouts
│      │      application.html.erb
│      │
│      └─users
│              edit.html.erb
│              index.html.erb
│              index.json.jbuilder
│              new.html.erb
│              show.html.erb
│              show.json.jbuilder
│              _form.html.erb
│
├─db
│  └─migrate
│          20140527044704_create_users.rb
│
└─test
    ├─controllers
    │      users_controller_test.rb
    │
    ├─fixtures
    │      users.yml
    │
    ├─helpers
    │      users_helper_test.rb
    │
    └─models
            user_test.rb

以降、MVCに沿って説明していく。


コントローラ(C)について

■ルーティング

rake routes」コマンドを実行すると以下のように表示され、アプリのルーティング構造がわかる。

C:\rubyWorkspace\scaffolding>rake routes
   Prefix Verb   URI Pattern               Controller#Action  [(※)説明]    [(※)Viewテンプレート(.html / .json)]
    users GET    /users(.:format)          users#index         一覧          index.html.erb / index.json.jbuilder
          POST   /users(.:format)          users#create        新規登録      
 new_user GET    /users/new(.:format)      users#new           新規登録画面  new.html.erb
edit_user GET    /users/:id/edit(.:format) users#edit          編集画面      edit.html.erb
     user GET    /users/:id(.:format)      users#show          個別詳細      show.html.erb / show.json.jbuilder
          PATCH  /users/:id(.:format)      users#update        更新          
          PUT    /users/:id(.:format)      users#update        更新          
          DELETE /users/:id(.:format)      users#destroy       削除          

(※)の箇所は実際は表示されない。
:id」はusersテーブルのidカラム(プライマリキー)に該当する。
(.:format)」はURIの最後に「.html」や「.json」をのようなフォーマットを許容する、という意味。
(.:format)」の部分に
何もつけなかったり「.html」をつけるとERBが、
.json」をつけるとJBuilder
Viewのテンプレートとして自動的に選択される。(試しにブラウザで「http://localhost:3000/users.json」へアクセスするビックリ。実際には自動選択されるのではなく、後述のrespond_toメソッドを参照。)
rake routes」コマンドで表示したような/usersに対するURIとusersコントローラクラスおよびアクションメソッド(index, create, new ,edit, show, update, destroy)へのマッピングはroutes.rbresourcesメソッドを使用した一行を定義するだけで実現される。

Rails.application.routes.draw do
  resources :users    #←ここ!!
end

resource(単数形)というメソッドもあるので注意されたし。

■フィルタ

Usersコントローラクラス(users_controller.rb)にbefore_actionというキーワードで下記のような記載がある。

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy] # ←ここ!
  
  # 〜省略〜

end

これは、showeditupdatedestroyアクションメソッドを実行するset_userメソッドを実行する、というフィルタ機能を提供するもの。
アクションメソッドのにフィルタを実行したい場合はafter_action
アクションメソッドの前後にフィルタを実行したい場合はaround_actionがある。

■paramsメソッド

コントローラクラスでクライアントから送信されたリクエスト情報を取得するためにparamsメソッドを使用する。
下記のフォーマットでパラメータ値を取得することができる。

params[:パラメータ名]


取得できるデータとして、Formデータクエリパラメータ値ルートパラメータ値(URI「/users/1234」の「1234」部分)がある。
ルートパラメータ値は「params[:id]」で取得できる。

■StrongParameters

下記のようにparamsメソッドを使用してパラメータのフィルタリングを行って取得するパラメータをStrongParametersという。

params.require(モデル).permit(取得する項目名, 取得する項目名, ...)



■respond_toメソッド

コントローラクラスでrespond_toメソッドはマルチフォーマット(HTMLやJSON)に対応したレスポンスを返却したい場合に使用する。

respond_to do |format|
  format.[フォーマット] { 処理 }
  ...
end


[フォーマット]の部分にhtmljson等のフォーマットタイプを記載する。
フォーマットのタイプによってテンプレートが選択される。(htmlであればERB、jsonであればJBuilder)
処理の部分にテンプレートへ引き渡す値などのロジックを記述する。
新規にフォーマットタイプを追加したい場合「config/initializers/mime_types.rb」へ追記する。


【独り言】
これってJAX-RSでいうところのコンテンツネゴシエーションの代わり?だとしたらクライアントから「Accept-XXX」系で欲しいコンテンツをコントロールするにはheadersメソッド使ってゴリゴリロジック書くしかないのか?

■redirect_toメソッド

コントローラクラスで他のURIへリダイレクトさせたい場合、redirect_toメソッドを使用する。

redirect_to "URI" [, :status => ステイタスコード, オプション]


"URI"の部分は様々な表現が可能。永続化したモデルのテンプレート変数(例えば、@user)を指定するとそのモデルに該当するshowアクションメソッドへリダイレクトできる。
また、オプションに「:notice」を使用すると、リダイレクト先のテンプレートに「<%= notice %>」を記載しておくことで任意の文字列を表示させることができる。

■renderメソッド

コントローラクラスで使用することにより指定したテンプレートを表示したり、指定したアクションメソッド呼び出すことができる。

render オプション


その他コントローラで使用できるメソッド・詳細は下記を参照。
http://railsdoc.com/controller


ビュー(C)について

EBRテンプレートにはビューヘルパーというコントローラとの情報のやり取りをスムーズに、そして簡単に表現できる機能がある。(種類が数十個あり、覚えるのはシンドイ。。。)
ヘルパーメソッドという単位で機能が提供されている。

ヘルパーメソッド フォーマット 説明 記載例 生成結果
link_to link_to "リンクテキスト", "URI" [,オプション, HTMLオプション] ハイパーリンクを生成 <%= link_to "ほげ", "http://hoge", :class => "hoge" %> <a class="hoge" href="http://hoge">ほげ</a>

上記フォーマットの"URI"部分についてはオブジェクト変数と「rake routes」コマンドを実行した際に得られるPrefixを駆使することによりURIをハードコーディングせずに自動生成が可能。

"URI"部分の書き方 説明 記載例 生成結果例
[indexアクションのPrefix]_path アクションメソッドindexに該当するハイパーリンクを生成 <%= link_to "インデックス", users_path %> <a href="http://localhost:3000/users">インデックス</a>
[newアクションのPrefix]_path アクションメソッドnewに該当するハイパーリンクを生成 <%= link_to "ニュー", new_user_path %> <a href="http://localhost:3000/users/new">ニュー</a>
[editアクションのPrefix]_path(オブジェクト変数) アクションメソッドeditに該当するハイパーリンクを生成 <%= link_to "エディット", edit_user_path(user) %> <a href="http://localhost:3000/users/1234/edit">エディット</a>
[showアクションのPrefix]_path(オブジェクト変数) アクションメソッドshowに該当するハイパーリンクを生成 <%= link_to "ショー", user_path(user) %> <a href="http://localhost:3000/users/1234">ショー</a>
オブジェクト変数 上記の省略系 <%= link_to "ショー", user %> <a href="http://localhost:3000/users/1234">ショー</a>

上記は、routes.rbにおいてresourcesresourceを用いてルーティング設定を行ったときに使用できる。
また、「{:controller => "users", :action => "new"}」のようにコントローラクラスとアクションメソッドを指定する方法もある。
JSFみたいにコンポーネントベースで記載もできるってことで理解した。
その他ビューヘルパー機能については下記を参照。
http://railsdoc.com/view


モデル(M)について

users_controller.rbに「@users = User.all」やら「@user.save」といった記載がある。
これはActiveRecordの機能を用いてモデルオブジェクトをCRUDしている。
下記に記述フォーマット、代表的な機能を記す。

モデル.メソッド([引数])

メソッド 説明
new モデルオブジェクトの生成
find データベースから検索してモデルオブジェクトを取得
all データベースから全てのレコードを取得
save モデルオブジェクトをデータベースへ保存
update 条件に当てはまるデータベース上のレコードを更新
destroy モデルオブジェクトに該当するデータベース上のレコードを削除

上記メソッドは代表的なもののみで、その他メソッド・詳細は下記を参照。
http://railsdoc.com/model


補足

一見万能に見えるscaffoldingであるが、以下の問題(というか特徴)がある。

  • データの入力チェックが行われていない
    • StrongParametersは使用されているが、入力値の検証は行われていない
  • ユーザ認証が行われていない
  • Viewがしょぼい