Rails Tutorial 第三章 簡易まとめ (動的ページへの編集)

  • 0
    いいね
  • 0
    コメント

    目標

    Homeページ、Helpページ、Aboutページをそれぞれ編集し、最終的にページごとに異なるタイトルを表示することです。ここではビューのtitleタグの内容を変更

    <ページ名> | Ruby on Rails Tutorial Sample App

    フロウ

    ページタイトルの簡単なテストを書き (red)
          ↓
    3つのページにタイトルを追加し (green)
          ↓
    レイアウトファイルを活用してコードの重複を解決します (REFACTOR)

    テストを実装(RED)

    アサーションメソッド

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

    →titleタグ内に”Home | Ruby on Rails Tutorial Sample App”という文字列があるかどうかをチェック

    このコードをそれぞれのアクションテストファイルに書き込む

    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
        assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
      end
    
      test "should get help" do
        get static_pages_help_url
        assert_response :success
        assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
      end
    
      test "should get about" do
        get static_pages_about_url
        assert_response :success
        assert_select "title", "About | Ruby on Rails Tutorial Sample App"
      end
    end
    

    テスト:RED

    タイトルを追加(GREEN)

    app/views/static_pages/home.html.erb
     <h1>Sample App</h1>
    <p>
      This is the home page for the
      <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
      sample application.
    </p>
    

    現在のhtmlファイルに基本構造を持たせる

    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="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
          sample application.
        </p>
      </body>
    </html>
    

    help、aboutページもそれぞれ編集。
    テスト:GREEN

    レイアウトと埋め込みRuby (Refactor)、「DRY」(Don’t Repeat Yourself)という原則

    重複コードをまとめ、きれいでスマートを目指す

    「Ruby on Rails Tutorial Sample App」という基本タイトルは、各テストで毎回同じ内容を書いてしまっています。そこで、setupという特別なメソッド (各テストが実行される直前で実行されるメソッド) を使って、この問題を解決したい

    変数を利用

    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
    
      test "should get home" do
        get static_pages_home_url
        assert_response :success
        assert_select "title", "Home | #{@base_title}"
      end
    
      test "should get help" do
        get static_pages_help_url
        assert_response :success
        assert_select "title", "Help | #{@base_title}"
      end
    
      test "should get about" do
        get static_pages_about_url
        assert_response :success
        assert_select "title", "About | #{@base_title}"
      end
    end
    

    テスト:GREEN

    provideメソッドを活用する

    ・ページのタイトルがどれもほぼ同じ (完全にではないが)。そこで。。。

    最初にコードを若干追加して、現在は「ほぼ」同じになっているページのタイトルを完全に同じにしておきます。この方が、コードの重複を一括で取り除けるからです。

    重複を取り除くテクニックの1つとして、ビューで「埋め込みRuby」(Embedded Ruby) が使えます。Home、Help、Aboutページには可変要素があるので、Railsのprovideメソッドを使ってタイトルをページごとに変更します。試にhome.html.erbビューのコード内のタイトルに含まれている "Home" という文字を置き換えて、動作を確認してみましょう

    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="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
          sample application.
        </p>
      </body>
    </html>
    

    ERB(Enbedded RuBy)

    はWebページに動的な要素を加えるときに使うテンプレートシステムです
    上のコードでは「<% ... %>」という記法が使われており、その中からRailsのprovideメソッドを呼び出しています。メソッドの引数では、"Home"という文字列と:titleというラベルを関連付けています。そしてタイトルの部分では、上の記法と連携する「<%= ... %>」というよく似た記法を使い、その中でRubyのyieldメソッドを呼び出しています。このメソッドによって、テンプレートのその部分に実際のタイトルが挿入されます。

    help,aboutもそれぞれ。

    テスト:GREEN

    HTMLの構造全体が各ページで重複しているのでapplication.html.erbにまとめる

    タイトルの可変部分をERBを使って置き換えたので、現在それぞれのページは次のような構造になっています。

    <% provide(:title, "The Title") %>
    <!DOCTYPE html>
    <html>
      <head>
        <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
      </head>
      <body>
        Contents
      </body>
    </html>
    

    こうして見ると、HTMLの構造はtitleタグの内容も含めてどのページも完全に同じ。異なる点があるとすれば、bodyタグの内側のcontentsだけ。

    一辺に変更をできる
    application.html.erbに変更を与える

    app/views/layouts/application.html.erb
     <!DOCTYPE html>
    <html>
      <head>
        <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
        <%= csrf_meta_tags %>
        <%= stylesheet_link_tag    'application', media: 'all',
                                   'data-turbolinks-track': 'reload' %>
        <%= javascript_include_tag 'application',
                                   'data-turbolinks-track': 'reload' %>
      </head>
    
      <body>
        <%= yield %>
      </body>
    </html>
    

    <%= yield %>
    このコードは、各ページの内容をレイアウトに挿入するためのものです。ここでは、このコードの詳細な動作を正確に理解することは重要ではありません。レイアウトを使う際に、/static_pages/homeにアクセスするとhome.html.erbの内容がHTMLに変換され、<%= yield %>の位置に挿入される、ということだけ理解しておけば問題ありません。

    それぞれのビューの重複部分を削除
    例)home

    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="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
          sample application.
        </p>
      </body>
    </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="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
      sample application.
    </p>
    
    app/views/static_pages/help.html.erb
     <% provide(:title, "Help") %>
    <h1>Help</h1>
    <p>  Get help on the Ruby on Rails Tutorial at the
      <a href="https://railstutorial.jp/help">Rails Tutorial help section</a>.
      To get help on this sample app, see the
      <a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em>
      book</a>.
    </p>
    
    app/views/static_pages/about.html.erb
     <% provide(:title, "About") %>
    <h1>About</h1>
    <p>
      <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
      is a <a href="https://railstutorial.jp/#ebook">book</a> and
      <a href="https://railstutorial.jp/#screencast">screencast</a>
      to teach web development with
      <a href="http://rubyonrails.org/">Ruby on Rails</a>.
      This is the sample application for the tutorial.
    </p>
    

    テスト:GREEN

    ルーティング設定

    config/routes.rb
     Rails.application.routes.draw do
      root 'static_pages#home'
      get  'static_pages/home'
      get  'static_pages/help'
      get  'static_pages/about'
    end