Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

【Ruby on Railsチュートリアル(第4版)】第3章 ほぼ静的なページの作成(演習と解答)

はじめに

このブログ記事は、私(Kodak)自身のRailsの勉強記録として書いています。
Ruby on Railsチュートリアル』の演習と解答をもくもくと書いているだけの記事なので、興味の無い方は軽くスルーしてあげてください。他にも、まだ『Railsチュートリアル』の演習に挑戦していない方、これから『Railsチュートリアル』をやるぞ!という方は(演習の解答の)ネタバレになりますので、スルーしてください。

Ruby on Rails チュートリアルとは?

Ruby業界でRailsを使い始めるなら、まず最初に初めるRails入門サイトです。
電子書籍版は有料ですが、Webサイトにあるオンライン版は無料なので、誰でも読む(Railsにチャレンジする)事ができます。
railstutorial.jp
全部で14章あり、かなりのボリュームですが、これを読む事でRailsの基礎を学ぶ事ができ、ちょっとしたWebアプリケーションを作れるレベルにはなれる?とのこと。
各章毎に演習問題が複数あり、これを解いていく事でRailsへの理解を深めていく事ができる様になっています。

環境について

Ruby 2.5.0-dev
Rails 5.1.4
・バージョン管理ツール:GitHub(https://github.com/Kodak4400)

演習と解答

3.1 セットアップ<演習>
1. BitbucketがMarkdown記法のREADME (リスト 3.3) をHTMLとして正しく描画しているか、確認してみてください。
【解答】以下の通り。
f:id:special-moucom:20180707200309p:plain

2. 本番環境 (Heroku) のルートURLにアクセスして、デプロイが成功したかどうか確かめてみてください。
実機操作のため割愛。


3.2.1 静的なページの生成<演習>
1. Fooというコントローラを生成し、その中にbarとbazアクションを追加してみてください。
【解答】以下の通り。

$ rails g controller Foo bar baz
      create  app/controllers/foo_controller.rb
       route  get 'foo/baz'
       route  get 'foo/bar'
      invoke  erb
      create    app/views/foo
      create    app/views/foo/bar.html.erb
      create    app/views/foo/baz.html.erb
      invoke  test_unit
      create    test/controllers/foo_controller_test.rb
      invoke  helper
      create    app/helpers/foo_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/foo.coffee
      invoke    scss
      create      app/assets/stylesheets/foo.scss
$

2. コラム 3.1で紹介したテクニックを駆使して、Fooコントローラとそれに関連するアクションを削除してみてください。
【解答】以下の通り。

$ rails d controller Foo bar baz
      remove  app/controllers/foo_controller.rb
       route  get 'foo/baz'
       route  get 'foo/bar'
      invoke  erb
      remove    app/views/foo
      remove    app/views/foo/bar.html.erb
      remove    app/views/foo/baz.html.erb
      invoke  test_unit
      remove    test/controllers/foo_controller_test.rb
      invoke  helper
      remove    app/helpers/foo_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      remove      app/assets/javascripts/foo.coffee
      invoke    scss
      remove      app/assets/stylesheets/foo.scss
$

3.4.2 タイトルを追加する(Green)<演習>
1. StaticPagesコントローラのテスト (リスト 3.24) には、いくつか繰り返しがあったことにお気づきでしょうか? 特に「Ruby on Rails Tutorial Sample App」という基本タイトルは、各テストで毎回同じ内容を書いてしまっています。そこで、setupという特別なメソッド (各テストが実行される直前で実行されるメソッド) を使って、この問題を解決したいと思います。まずは、リスト 3.30のテストが green になることを確認してみてください (リスト 3.30では、2.2.2で少し触れたインスタンス変数や文字列の式展開というテクニックを使っています。それぞれ4.4.5と4.2.2で詳しく解説するので、今はわからなくても問題ありません)。
【解答】以下の通り。

### [static_pages_controller_test.rb]

require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest
  # setupメソッドの追加
  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end

  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "Contact|#{@base_title}"
  end
end
### [テストの実行]

$ rails t
/Users/Kodak/00_myfolder/00_devlop/03_Ruby_on_Rails/rails-tutorial/sample_app/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /Users/Kodak/00_myfolder/00_devlop/03_Ruby_on_Rails/rails-tutorial/sample_app/config/application.rb to limit the frameworks that will be loaded.
Run options: --seed 19048

# Running:

Run options: --seed 19048

# Running:

・
・
・

# 正常終了した事を確認
Finished in 0.350625s, 11.4082 runs/s, 22.8164 assertions/s.
4 runs, 8 assertions, 0 failures, 0 errors, 0 skips



Finished in 0.370653s, 10.7918 runs/s, 21.5835 assertions/s.
4 runs, 8 assertions, 0 failures, 0 errors, 0 skips
$

3.4.3 レイアウトと埋め込みRuby(Refactor)<演習>
1. サンプルアプリケーションにContact (問い合わせ先) ページを作成してください (ヒント: まずはリスト 3.15を参考にして、/static_pages/contactというURLのページに「Contact | Ruby on Rails Tutorial Sample App」というタイトルが存在するかどうかを確認するテストを最初に作成しましょう。 次に、3.3.3でAboutページを作ったときのと同じように、Contactページにもリスト 3.40のコンテンツを表示してみましょう。)。
【解答】以下の通り。

### [test/controllers/static_pages_controller_test.rb]
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end
  # contactのテストを作成
  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "Contact|#{@base_title}"
  end

end
<!-- ### [app/views/static_pages/contact.html.erb] -->
<% provide(:title, "Contact") %>
<h1>Contact</h1>
<p>
Contact the Ruby on Rails Tutorial about the sample app at the
<a href="https://railstutorial.jp/contact">contact page</a>.
</p>
### [app/controllers/static_pages_controller.rb]
class StaticPagesController < ApplicationController

  def contact
  end

end
### [config/routes.rb]
Rails.application.routes.draw do
  get 'static_pages/contact'

  get 'static_pages/home'
  get 'static_pages/help'
  get 'static_pages/about'
  root 'application#hello'
end

3.4.4 ルーティングの設定<演習>
1. リスト 3.41にrootルーティングを追加したことで、root_urlというRailsヘルパーが使えるようになりました (以前、static_pages_home_urlが使えるようになったときと同じです)。リスト 3.42のFILL_INと記された部分を置き換えて、rootルーティングのテストを書いてみてください。
【解答】以下の通り。

### [test/controllers/static_pages_controller_test.rb]
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end
  # root_urlに置き換え
  test "should get root" do
    get root_url
    assert_response :success
    assert_select "title", "Contact|#{@base_title}"
  end

end

2. 実はリスト 3.41のコードを書いていたので、先ほどの課題のテストは既に green になっているはずです。このような場合、テストを変更する前から成功していたのか、変更した後に成功するようになったのか、判断が難しいです。リスト 3.41のコードがテスト結果に影響を与えていることを確認するため、リスト 3.43のようにrootルーティングをコメントアウトして見て、 red になるかどうか確かめてみましょう (なおRubyのコメント機能については4.2.1で説明します)。最後に、コメントアウトした箇所を元に戻し (すなわちリスト 3.41に戻し)、テストが green になることを確認してみましょう。
【解答】以下の通り。

### [config/routes.rb]
Rails.application.routes.draw do
  # 以下コメントアウト
  # root 'static_pages#home'
  get 'static_pages/contact'
  get 'static_pages/home'
  get 'static_pages/help'
  get 'static_pages/about'
end
### エラーになった事を確認
Error:
StaticPagesControllerTest#test_should_get_root:
NameError: undefined local variable or method `root_url' for #<StaticPagesControllerTest:0x00007f9717099b00>
    test/controllers/static_pages_controller_test.rb:34:in `block in <class:StaticPagesControllerTest>’
### [config/routes.rb]
Rails.application.routes.draw do
  # コメントアウトをはずす
  root 'static_pages#home'
  get 'static_pages/contact'
  get 'static_pages/home'
  get 'static_pages/help'
  get 'static_pages/about'
end
### 正常終了した事を確認
Finished in 0.402751s, 12.4146 runs/s, 24.8292 assertions/s.
5 runs, 10 assertions, 0 failures, 0 errors, 0 skips