らくだ🐫にもできるRailsチュートリアル|5.3

5.3 レイアウトのリンク

‘#’でダミーリンクにしていた部分を書き換えていく。
<a href=”/static_pages/about”>About</a>の様に直接パスを指定するのではなく
Railsの慣習に倣った形式で記述していく
→<%= link_to “About”, about_path %>
埋め込みRuby Link_toヘルパー 表示される文字(第一引数),リンクのパス(第2引数)

about_pathとは何ぞ

名前付きルート(○○_path)
config/routes.rbで設定することで使えるようになる
(詳しくは5.3.2、5.3.3)

名前付きルートのいい所

Aboutページへのリンクを例に・・・
/static_pages/aboutの様にパスをしているすると、リンク先のパスに変更があった場合にすべての記述個所を修正しないといけない
about_pathで指定していれば、リンク先のパスに変更があってもroutes.rbで該当箇所を修正するだけでOK

5.3.1 Contactページ

3.4.3の演習でつくったものがそのまま残っているのでした。

/sample_app/test/controllers/static_pages_controller_test.rb
・
・
・
  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "Contact | #{@base_title}"
    #本文のリスト5.21はベースタイトルが文字列だけど、手元のデータは変数が定義されているのでそっちで
  end

end

5.3.2 RailsのルートURL

ルートURLの様にルーティングを定義するメリット
→名前付きルートを使えるようになる!→メソッドを通してURLを参照できる!

#routes.rbにルートURLを定義する
root 'static_pages#home'

#下記の様にメソッドを通して呼び出せるようになる
#ルートULL以下の文字列を返す
root_path -> '/'
#完全なURLを返す
root_url  -> 'https://○○○○○.vfs.cloud9.ap-northeast-1.amazonaws.com/'

なお、Railsチュートリアルでは一般的な規約に従い、基本的には_path書式を使い、リダイレクトの場合のみ_url書式を使うようにします。これはHTTPの標準としては、リダイレクトのときに完全なURLが要求されるためです。

静的ページの名前付きルートを定義する

#routes.rbでgetルールを使って定義(helpページの例)
get 'static_pages/help'
#↑これを こうする↓
get  '/help', to: 'static_pages#help'
#getリクエストが /helpに送信されたとき, static_pagesコントローラーの helpアクションが 呼び出される

#上記を定義することで名前付きルートが使えるようになる
help_path -> '/help'
help_url  -> 'https://○○○○○.vfs.cloud9.ap-northeast-1.amazonaws.com/help'

上記に倣ってroutes.rbを編集
static_pages_controller_test.rbの該当箇所も修正

/sample_app/config/routes.rb
Rails.application.routes.draw do
  root 'static_pages#home'
  get '/help',    to:'static_pages#help'
  get '/about',   to:'static_pages#about'
  get '/contact', to:'static_pages#contact'
end
/sample_app/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 root" do
    get root_path
    assert_response :success
    assert_select "title", "#{@base_title}"
  end


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

  test "should get about" do
    get about_path
    assert_response :success
    assert_select "title", "About | #{@base_title}"
  end
  
  test "should get contact" do
    get contact_path
    assert_response :success
    assert_select "title", "Contact | #{@base_title}"
  end

end

尚ベースタイトルが略

演習

  1. 実は名前付きルートは、as:オプションを使って変更することができます。有名なFar Sideの漫画に倣って、Helpページの名前付きルートをhelfに変更してみてください (リスト 5.29)。
  2. 先ほどの変更により、テストが redになっていることを確認してください。リスト 5.28を参考にルーティングを更新して、テストを greenにして見てください。
  3. エディタのUndo機能を使って、今回の演習で行った変更を元に戻して見てください。
/sample_app/config/routes.rb
#1.
Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help', as: 'helf'
  #:asオプションで指定した文字列で名前付きルートが定義される
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
end
/sample_app/test/controllers/static_pages_controller_test.rb
#2.
・
・
・
  test "should get help" do
    get helf_path
    assert_response :success
    assert_select "title", "Help | #{@base_title}"
  end
・
・
・
#3.
#動作確認が出来たらCtrl+zでUndo(win)(routes.rbも)

5.3.3 名前付きルート

名前付きルートを定義したので
本文に倣ってviewファイルのlink_toメソッドを書き換えていく

演習

  1. リスト 5.29のようにhelfルーティングを作成し、レイアウトのリンクを更新してみてください。
  2. 前回の演習と同様に、エディタのUndo機能を使ってこの演習で行った変更を元に戻してみてください。
/sample_app/app/views/layouts/_header.html.erb
#1.
#ルーティングは前回の演習と同様
・
・
・
       <ul class="nav navbar-nav navbar-right">
         <li><%= link_to "Home",   root_path %></li>
          <li><%= link_to "Help",   helf_path %></li>
          <li><%= link_to "Log in", '#' %></li>
        </ul>
・
・
・

2.リンクが作動することを確認してUndo

5.3.4 リンクのテスト

統合テストを使ってリンクが正しく動いているかをチェックする

統合テストとは

アプリケーションの動作を端から端まで (end-to-end) シミュレートしてテストするもの

ターミナル
$ rails generate integration_test site_layout
  #統合テストを生成するコマンド テストの名前
      invoke  test_unit
      create    test/integration/site_layout_test.rb
      #test/integration/にファイルが生成される 指定の文字列の末尾に_testが追加される

レイアウトのリンクに対するテスト

  1. ルートURL (Homeページ) にGETリクエストを送る.
  2. 正しいページテンプレートが描画されているかどうか確かめる.
  3. Home、Help、About、Contactの各ページへのリンクが正しく動くか確かめる.

上記の内容をコード化していく

/sample_app/test/integration/site_layout_test.rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  test "layout links" do  #layout links(テストの名前)
    get root_path                                   #ルートパスにgetのリクエスト
    assert_template 'static_pages/home'             #static_pages/homeが描写されている
    assert_select "a[href=?]", root_path, count: 2  #<a href="/">がある 2か所
    assert_select "a[href=?]", help_path            #<a href="/help">がある
    assert_select "a[href=?]", about_path           #<a href="/about">がある
    assert_select "a[href=?]", contact_path         #<a href="/contact">がある
  end
end

assert_selectメソッドとはなんぞ

様々なオプションを付けることが出来る便利で凄いメソッド(語彙)
RailsGuideの説明ページ
本文にあるassert_selectの使用例

assert_select "a[href=?]", about_path
#Railsが "?"にabout_pathを置き換えてくれる
#→<a href="/about"<.../a<と言うHTMLがあるかをチェックしている
assert_select "a[href=?]", root_path, count: 2
#オプションを付けることも出来る(指定のリンクが2つあるかどうかのチェック)

Rakeタスクとは何ぞ

そもそもRakeとは?→Rubyで書かれたビルドツール(プログラムを制御・統合するもの)
RailsドキュメントのRakeとは のページ
Rakeタスクとは→Rakefileというファイルに一連の処理を定義したもの

そういうものがある、と言う事を覚えておく!

統合テストが通るかどうかは下記のコマンド(Rakeタスク)を実行する事で試せる

$ rails test:integration

→統合テストが成功したらすべてのテストが成功するかも確認する

通常rake test:integrationで実行するものらしいし、調べた限りではrake test:integrationと出てくるですが
本文ではrails test:integrationなんですよね。
使い分け?とかどうなってるんでしょうか。はて。

→Rails5からrakeタスクをrailsコマンドで実行できるようになったとの事です。
勉強になりました!

演習

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

1.動作確認のみなので省略
2.↓

/sample_app/test/test_helper.rb
・
・
・
class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all
  include ApplicationHelper
  #ApplicationHelperを追加→ApplicationHelperで定義したヘルパーが使えるようになる
・
・
・
/sample_app/test/integration/site_layout_test.rb
・
・
・
    assert_select "a[href=?]", contact_path
    get contact_path
    #contact_pathへgetのリクエスト
    assert_select "title", full_title("Contact")
    #<title>Contact | Ruby on Rails Tutorial Sample App</title>がある
    #test_helperでApplicationHelperを使えるように定義した為full_titleが使えるようになっている
  end
end

/sample_app/app/helpers/application_helper.rbと
/sample_app/test/controllers/static_pages_controller_test.rbの
ベースタイトル部分を「Ruby on Rails Tutoial」に変更してテストしてみる→GREEN
誤字が起こっているのにテストがGREEN!→full_titleヘルパーをテストする

/sample_app/test/helpers/application_helper_test.rb
#testのフォルダ の中の helperのテストのフォルダ に application_helperのテストのファイル を作る
require 'test_helper'

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

→RED
エラーメッセージに沿って修正

assert_equalとはなんぞ

ユニットテストで使うメソッド(Railsドキュメント)
assert_equal(値1, 値2) →値1と値2が等しければ成功
値には変数も入る

まとめとか感想

名前付きルートはとても便利。

手元のコードと本文のコードで
「あれ?前回やった所はどこへ行ったの??」みたいなことがちょこちょこ起こるんだけど
なるべく手元のコードを優先で対応していけるようにしたい。

らくだ🐫にもできるRailsチュートリアルとは

「ド」が付く素人のらくだ🐫が勉強するRailsチュートリアルの学習記録です。
自分用に記録していますが、お役に立つことがあれば幸いです。

調べたとはいえらくだ🐫なりの解釈や説明が含まれます。間違っている部分もあるかと思います。そんな所は教えて頂けすと幸いなのですが、このブログにはコメント機能がありません💧お手数おかけしますがTwitterなどでご連絡いただければ幸いです