新米パパの育児留学

新米パパの育児留学

『育児留学』とは、育児を通して異なる視点を得たり新しいことに挑戦して自己成長に繋げること。育児奮闘中の新米パパが育児を通して得た気づきや感じたこと、育休中に習得したプログラミングに関する話題を発信していきます。

【第5章】Ruby on Rails チュートリアル 5.0(第4版)演習と解答まとめ

Ruby on Rails Tutorial最新版の演習と解答です。

目的

Ruby on Rails チュートリアル 5.0(第4版)を学習中です。

学習を進める中で演習問題の解答がなかった(*1,2)ので、自分なりにまとめていくこととしました。

アウトプットし、自分の理解を深めることを目的としています。 もし、記載内容に誤りがあった場合はコメントいただけると幸いです。

(*1)著者による有償版の解答はあるようです。正式な解答をご希望の方はこちらを参照ください。

Learn Web Development with Rails: Michael Hartl's Ruby on Rails Tutorial | Softcover.io

(*2)旧版に関する解答はありましたが、最新版 5.0(第4版)に関しては検索しても出てきませんでした。

演習問題と解答

演習5.1.1

演習5.1.1.1

<問題> Webページと言ったらネコ画像、というぐらいにはWebにはネコ画像が溢れていますよね。リスト 5.4のコマンドを使って、図 5.3のネコ画像をダウンロードしてきましょう。

<解答> 省略。

演習5.1.1.2

<問題> mvコマンドを使って、ダウンロードしたkitten.jpgファイルを適切なアセットディレクトリに移動してください (参考: 5.2.1)。

<解答>

$ mv kitten.jpg app/assets/images/

演習5.1.1.3

<問題> image_tagを使って、kitten.jpg画像を表示してみてください (図 5.4)。

<解答>

<%= image_tag("kitten.jpg") %>

演習5.1.2

演習5.1.2.1

<問題> リスト 5.10を参考にして、5.1.1.1で使ったネコ画像をコメントアウトしてみてください。また、ブラウザのHTMLインスペクタ機能を使って、コメントアウトするとHTMLのソースからも消えていることを確認してみてください。

<解答> 動作確認のみなので省略。

演習5.1.2.2

<問題> リスト 5.11のコードをcustom.scssに追加し、すべての画像を非表示にしてみてください。うまくいけば、Railsのロゴ画像がHomeページから消えるはずです。先ほどと同様にインスペクタ機能を使って、今度はHTMLのソースコードは残ったままで、画像だけが表示されなくなっていることを確認してみてください。

<解答> 動作確認のみなので省略。

演習5.1.3

演習5.1.3.1

<問題> Railsがデフォルトで生成するheadタグの部分を、リスト 5.18のようにrenderに置き換えてみてください。ヒント: 単純に削除してしまうと後でパーシャルを1から書き直す必要が出てくるので、削除する前にどこかに退避しておきましょう。

<解答>

[_rails_default.html.erb]

<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all',
'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

[application.html.erb]

(前略)
<head>
 <title><%= full_title(yield(:title)) %></title>
 <%= render 'layouts/rails_default' %>
 <%= render 'layouts/shim' %>
</head>
(後略)

演習5.1.3.2

<問題> リスト 5.18のようなパーシャルはまだ作っていないので、現時点ではテストは redになっているはずです。実際にテストを実行して確認してみましょう。

<解答> 動作確認のみなので省略。

演習5.1.3.3

<問題> layoutsディレクトリにheadタグ用のパーシャルを作成し、先ほど退避しておいたコードを書き込み、最後にテストが green に戻ることを確認しましょう。

<解答> 動作確認のみなので省略。

演習5.2.1

演習5.2.1.1

<問題> 5.2.2で提案したように、footerのCSSを手作業で変換してみましょう。具体的には、リスト 5.17の内容を1つずつ変換していき、リスト 5.20のようにしてみてください。

<解答> 動作確認のみなので省略。

演習5.3.2

演習5.3.2.1

<問題> 実は名前付きルートは、as:オプションを使って変更することができます。有名なFar Sideの漫画に倣って、Helpページの名前付きルートをhelfに変更してみてください。

<解答>

[static_pages_controller_test.rb]

test "should get help" do
  get helf_path
  assert_response :success
  assert_select "title", "Help | #{@base_title}"
end

演習5.3.2.2

<問題> 先ほどの変更により、テストが redになっていることを確認してください。リスト 5.28を参考にルーティングを更新して、テストを greenにして見てください。

<解答> 動作確認のみなので省略。

演習5.3.2.3

<問題> エディタのUndo機能を使って、今回の演習で行った変更を元に戻して見てください。

<解答> 動作確認のみなので省略。

演習5.3.3

演習5.3.3.1

<問題> リスト 5.29のようにhelfルーティングを作成し、レイアウトのリンクを更新してみてください。

<解答>

[routes.rb]

Rails.application.routes.draw do
(中略)
  get '/help', to: 'static_pages#help', as: 'helf'
(中略)
end

[_header.html.erb]

(前略)
<li><%= link_to "Help", helf_path %></li>
(後略)

演習5.3.3.2

<問題> 前回の演習と同様に、エディタのUndo機能を使ってこの演習で行った変更を元に戻してみてください。

<解答> 動作確認のみなので省略。

演習5.3.4

演習5.3.4.1

<問題> footerパーシャルのabout_pathをcontact_pathに変更してみて、テストが正しくエラーを捕まえてくれるかどうか確認してみてください。

<解答> 動作確認のみなので省略。

演習5.3.4.2

<問題> リスト 5.35で示すように、Applicationヘルパーで使っているfull_titleヘルパーを、test環境でも使えるようにすると便利です。こうしておくと、リスト 5.36のようなコードを使って、正しいタイトルをテストすることができます。ただし、これは完璧なテストではありません。たとえばベースタイトルに「Ruby on Rails Tutoial」といった誤字があったとしても、このテストでは発見することができないでしょう。この問題を解決するためには、full_titleヘルパーに対するテストを書く必要があります。そこで、Applicationヘルパーをテストするファイルを作成し、リスト 5.37のFILL_INの部分を適切なコードに置き換えてみてください。ヒント: リスト 5.37ではassert_equal <期待される値>, <実際の値>といった形で使っていましたが、内部では==演算子で期待される値と実際の値を比較し、正しいかどうかのテストをしています。

<解答> まず、リスト 5.35,5.36をガイドどおり修正。ベースタイトルに「Ruby on Rails Tutoial」といった誤字があった場合、エラーが出るか確認。

[application_helper_test]

module ApplicationHelper

 # ページごとの完全なタイトルを返します。 # コメント行
  def full_title(page_title = '') # メソッド定義とオプション引数
    base_title = "Ruby on Rails Tutoial Sample App" # 変数への代入
    if page_title.empty? # 論理値テスト
      base_title # 暗黙の戻り値
    else
      page_title + " | " + base_title # 文字列の結合
    end
  end
end

テスト結果はGREEN。エラー出ません。

次に、リスト5.37に従って、test作成

[application_helper_test.rb]

require 'test_helper'

class ApplicationHelperTest < ActionView::TestCase
  test "full title helper" do
    assert_equal full_title, "Ruby on Rails Tutorial Sample App"
    assert_equal full_title("Help"), "Help | Ruby on Rails Tutorial Sample App"
  end
end

テスト結果はRED。エラー出ました。

最後に、脱字を直して再度テスト。結果はGREEN。

演習5.4.1

演習5.4.1.1

<問題> 表 5.1を参考にしながらリスト 5.41を変更し、users_new_urlではなくsignup_pathを使えるようにしてみてください。

[users_controller_test.rb]

require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest
  test "should get new" do
    get signup_path
    assert_response :success
  end
end

演習5.4.1.2

<問題> 先ほどの変更を加えたことにより、テストが redになったことを確認してください。なお、この演習はテスト駆動開発 (コラム 3.3) で説明した red/green のリズムを作ることを目的としています。このテストは次の5.4.2で greenになるよう修正します。

<解答> 動作確認のみなので省略。

演習5.4.2

演習5.4.2.1

<問題> もしまだ5.4.1.1の演習に取り掛かっていなければ、まずはリスト 5.41のように変更し、名前付きルートsignup_pathを使えるようにしてください。また、リスト 5.43で名前付きルートが使えるようになったので、現時点でテストが greenになっていることを確認してください。

<解答> 動作確認のみなので省略。

演習5.4.2.2

<問題> 先ほどのテストが正しく動いていることを確認するため、signupルールの部分をコメントアウトし、テスト redになることを確認してください。確認できたら、コメントアウトを解除して greenの状態に戻してください。

<解答> 動作確認のみなので省略。

演習5.4.2.3

<問題> リスト 5.32の統合テストにsignupページにアクセスするコードを追加してください (getメソッドを使います)。コードを追加したら実際にテストを実行し、結果が正しいことを確認してください。 ヒント: リスト 5.36で紹介したfull_titleヘルパーを使ってみてください。

<解答>

[site_layout_test.rb]

require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest
  test "layout links" do
    get root_path
    assert_template 'static_pages/home'
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
    get contact_path
    assert_select "title", full_title("Contact")
    get signup_path
    assert_select "title", full_title("Sign up")
  end
end

関連記事

mochikichi.hatenablog.com