Help us understand the problem. What is going on with this article?

[Ruby入門 Rails5編] 04. コントローラの作成とテスト

More than 3 years have passed since last update.

前回は、MVCの全体像を、引きのショットでざっくり眺めてみた。
今回はMVCの肝となるコントローラを作成する手順を学ぶ。
あと、コントローラに対するテストも書いてみる。

【1】準備


いままで何度かやった手順なのでざっと〜。

① アプリケーションの作成

cd /docker-host/share/webapps/

rails _5.1.1_ new sample_app

 
② Gemを追加

# Gemfileを開く
cd /docker-host/share/webapps/sample_app
vi Gemfile

# 以下を追記
group :test do
  gem 'rails-controller-testing'
  gem 'minitest-reporters'
  gem 'guard'
  gem 'guard-minitest'
end

# あとgem取得先のURLをhttpに変更
source 'https://rubygems.org'source 'http://rubygems.org'

# んでインストール
bundle install --path vendor/bundle

 
③ gitにコミット
git add .
git commit -m "sample_app作成"

 
④ とりあえず動作確認

# Puma起動。「rails s」は「rails server」の短縮形
$ rails s
=> Booting Puma
〜 中略 〜
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

# んで、ブラウザから以下でアクセスできればOK
http://localhost:3000/

# 確認できたら、Pumaはいったん停止する( Ctrl-C )

 

【2】コントローラを生成する


「rails generate 〜」で、コントローラを生成してみる。

 
① コントローラの生成

cd /docker-host/share/webapps/sample_app

# 「StaticPages」コントローラを作って "home" と "help" というアクションを定義
rails generate controller StaticPages home help

# 何がつくられたか
$ git status -s
 M config/routes.rb
?? app/assets/javascripts/static_pages.coffee
?? app/assets/stylesheets/static_pages.scss
?? app/controllers/static_pages_controller.rb
?? app/helpers/static_pages_helper.rb
?? app/views/static_pages/
?? test/controllers/static_pages_controller_test.rb

# views/* の下には何がつくられたか
$ ls -1 app/views/static_pages/
help.html.erb
home.html.erb


# gitにコミット
git add .
git commit -m "StaticPagesコントローラを生成"

生成されるファイルは、前回のscaffoldの生成物から、モデルやDB関連を除いたもの、となっているようだ。
・コントローラ
・ビュー
・ヘルパー
・JSやCSSなどのassets関連
・テスト関連

また、scaffold のときと同様に、ルーティング設定ファイル「 config/routes.rb 」も編集されている。

 
② 表示確認

# Puma起動
$ rails s
=> Booting Puma
〜 中略 〜
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

# んで、ブラウザから以下のURLにアクセスできればOK
http://localhost:3000/static_pages/home
http://localhost:3000/static_pages/help

# 確認できたら、Pumaはいったん停止する( Ctrl-C )

 

[補足] generate したけど取り消したい

rails generate controller StaticPages home help
↓に対して...
rails destroy  controller StaticPages home help

rails generate model User name:string email:string
↓に対して...
rails destroy model User

など。

 

【3】ルーティングの設定を確認する


「 config/routes.rb 」

Rails.application.routes.draw do
  get 'static_pages/home'

  get 'static_pages/help'

  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

上記は、getメソッドで static_pages/xxx というURLにアクセスすると、StaticPages コントローラのxxxアクションを実行するよ〜、という設定。

 

【4】コントローラのソースを確認する


「app/controllers/static_pages_controller.rb」

class StaticPagesController < ApplicationController
  def home
  end

  def help
  end
end

「rails generate 〜」で指定したアクションのメソッドが定義されている。
命名規則で紐付いたビューを表示するだけなので、処理は何も記述されていない。

 

【5】ビューのソースを確認する


「app/views/static_pages/home.html.erb」
「app/views/static_pages/help.html.erb」

<h1>StaticPages#home</h1>
<p>Find me in app/views/static_pages/home.html.erb</p>

今回は特になにも書いてないな...

「 app/views/コントローラ名のスネークケース/アクション名.html.erb 」
という命名規則に従うことで、コントローラのアクションと紐付いているというところがポイントかな。

 

【6】コントローラのテストを書いてみる


scaffold や generate の結果確認で見たように、Rails ではデフォルトのソース群に既にテスト用のリソースが含まれている。
なので、面倒な導入なしにいきなりテストを書ける。

 

[準備] テストの出力をかっこよくする(任意)

さきの手順でプロジェクトに追加済みの minitest reporters というGemを有効にすると、テストの結果出力が綺麗になってちょっとテンション上がる。
以下のファイルにGemを利用するように記述する。

「test/test_helper.rb」

require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'

# ↓この2行を追加
require "minitest/reporters"
Minitest::Reporters.use!

class ActiveSupport::TestCase
 中略 
end

 
① どんなテストが生成されているのか確認する

コントローラとセットで生成されたテストコードの、デフォルトの状態は以下。

「test/controllers/static_pages_controller_test.rb」

require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest
  test "should get home" do
    get static_pages_home_url
    assert_response :success
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
  end

end

各アクションに対してテストが定義されていて、そのアクションのURLに対してGETでアクセスし、結果が :success(HTTPレスポンス200)かどうかをテストしている。
文法的には、test メソッドに 引数 と ブロックを渡しているのかな。

この段階でいっかいテストを実行してみると、以下のように何事もなく成功する。
※Pumaの起動は必要ない。かわりに Spring というサーバーを起動して実行するので、少し時間がかかる。

$ rails test
Running via Spring preloader in process 517
〜 中略 〜
Started with run options --seed 15128

  2/2: [=============================] 100% Time: 00:00:14, Time: 00:00:14

Finished in 14.31579s
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips

 
② これからコントローラに実装する機能に対するテストを先に書いて失敗させてみる

いわゆるテストファーストというやつ。
ここでは、新規に about というアクションを追加する想定で、先にテストコードを書いてみる。

「test/controllers/static_pages_controller_test.rb」

require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

   中略 

  # about アクションへのGETが成功するか
  test "should get about" do
    get static_pages_about_url
    assert_response :success
  end

end

んで、テストを実行して、失敗することを確認しておく。

$ rails test
Running via Spring preloader in process 611
〜 中略 〜
ERROR["test_should_get_about", StaticPagesControllerTest, 14.417123627001274]
〜 中略 〜
NameError:         NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x0055be52dfee48>
            test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'
〜 中略 〜
3 tests, 2 assertions, 0 failures, 1 errors, 0 skips

 
③ about アクションを追加する

③-a コントローラにアクションを追加

「app/controllers/static_pages_controller.rb」

# これを追加
def about
end

 
③-b ルーティング設定を追加

「config/routes.rb」

# これを追加
get 'static_pages/about'

 
③-c ビューを新規作成

「app/views/static_pages/about.html.erb」

<% # とりあえずこんな内容で作成 %>
<h1>StaticPages#about</h1>
<p>This is `about` page!</p>

 
④ んで、再度テストしてみる

$ rails test
〜 中略 〜
3 tests, 3 assertions, 0 failures, 0 errors, 0 skips

通った!

今回はなんか簡単でしたが、ひとまず コントローラの作成とテストについて学ぶことができた。
コントローラの詳細については回を追って順次学んでいく想定。
今日はここまで!

prgseek
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした