ぞえの技術めも

Ruby on Rails勉強中

【15日目】【1日20分のRailsチュートリアル】少しだけ動的なページを作成する

Ruby on Railsチュートリアル(第3版)

今日は「3.4 少しだけ動的なページ」から。

3.4 少しだけ動的なページ

HTMLページのヘッダの<title>タグの内容を動的に変更するように対応する。
今は各HTMLページのヘッダは共通になっているそう。

app/views/layouts/application.html.erbが共通のレイアウトファイルらしい。
これからの作業のためにリネームしてこれを使わない環境にする。

$ mv app/views/layouts/application.html.erb layout_file

3.4.1 タイトルをテストする (Red)

HTML構造について簡単な説明あり。

assert_selectメソッドで特定のHTMLタグが存在するかどうかテストできるらしい。

test/controllers/static_pages_controller_test.rb

assert_select "title", "Home | Ruby on Rails Tutorial Sample App"

<title>タグの中身を確認するテストコード。
上記のテストコードをHome/Help/Aboutにそれぞれ追加する。

(上のテストコードで繰り返し使われている「Ruby on Rails Tutorial Sample App」という文字列を一刻も早くリファクタリングしたくてたまらない方には、3.6の演習をおすすめします。)

リファクタリングしたくてたまらないけど順番にやっていきます。

テスト実行。

$ bundle exec rake test
    :
  1) Failure:
StaticPagesControllerTest#test_should_get_home [/home/ubuntu/workspace/sample_app/test/controllers/static_pages_controller_test.rb:7]:
<Home | Ruby on Rails Tutorial Sample App> expected but was
<SampleApp>..
Expected 0 to be >= 1.


  2) Failure:
StaticPagesControllerTest#test_should_get_about [/home/ubuntu/workspace/sample_app/test/controllers/static_pages_controller_test.rb:19]:
<About | Ruby on Rails Tutorial Sample App> expected but was
<SampleApp>..
Expected 0 to be >= 1.


  3) Failure:
StaticPagesControllerTest#test_should_get_help [/home/ubuntu/workspace/sample_app/test/controllers/static_pages_controller_test.rb:13]:
<Help | Ruby on Rails Tutorial Sample App> expected but was
<SampleApp>..
Expected 0 to be >= 1.

3 runs, 6 assertions, 3 failures, 0 errors, 0 skips

失敗しました。
この失敗を修正していく。

3.4.2 タイトルを追加する (Green)

まずはテストを通すためだけに各ページのテンプレートファイルを修正する。

重複しまくりで全然スマートじゃないけどここは我慢。

app/views/static_pages/home.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>Home | Ruby on Rails Tutorial Sample App</title>
  </head>
  <body>
    <h1>Sample App</h1>
    <p>
      This is the home page for the
      <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
      sample application.
    </p>
  </body>
</html>

HelpページとAboutページのテンプレートも同様に修正。

$ bundle exec rake test
    :
3 runs, 6 assertions, 0 failures, 0 errors, 0 skips

これでテストは通りました。

3.4.3 レイアウトと埋め込みRuby (Refactor)

さていよいよリファクタリングです。

・ページのタイトルがどれもほぼ同じ (完全にではないが)。
・「Ruby on Rails Tutorial Sample App」という文字が3つのタイトルで繰り返し使われている。
・HTMLの構造全体が各ページで重複している。

重複するコードは重複部分に何らかの修正があった場合、修正漏れも引き起こすし修正もめんどくさいしでいいことないのです。
できる限りスマートにしたい。

Railsprovide関数を使うそう。
provide関数がどういう関数なのかよく分からないけど変数に値を入れる関数なのかな。。。

app/views/static_pages/home.html.erb

<% provide(:title, "Home") %>
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
  </head>
  <body>
    <h1>Sample App</h1>
    <p>
      This is the home page for the
      <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
      sample application.
    </p>
  </body>
</html>

ERBファイルにおいて<% ... %>「コード実行のみ(結果出力なし)」<%= ... %>「コード実行&実行結果出力」の違いがあるそう。

HelpページとAboutページのテンプレートも同様に修正。

修正完了したらテスト実行。問題なし。

$ bundle exec rake test
    :
3 runs, 6 assertions, 0 failures, 0 errors, 0 skips

さて、こうなってくるとヘッダの内容は各ファイルでほぼ同じになってきました。
重複しまくりです。

ここでレイアウトファイルの登場。
まずはリネームしていたレイアウトファイルを元に戻します。

$ mv layout_file app/views/layouts/application.html.erb

レイアウトファイルの<title>部分を下記のように修正。

<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>

レイアウトファイルの他のERBコードについてちょろっと説明あり。
また追々理解できるでしょう。

HTMLのヘッダ部分を各テンプレートに書いておく必要がなくなったので削除。
シンプルになりました。

app/views/static_pages/home.html.erb

<% provide(:title, "Home") %>
<h1>Sample App</h1>
<p>
  This is the home page for the
  <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
  sample application.
</p>

最後にテスト実行して修正が問題ないことを確認。

$ bundle exec rake test
    :
3 runs, 6 assertions, 0 failures, 0 errors, 0 skips

キリのいいところまでしたかったので今日の作業時間は長めの【38分】
リファクタリングって結構胸踊ります。
実装するよりもいかにきれいなコードに仕上げるか、の方が好きかも?

次は「3.4.4 ルーティングの設定」から。