おぴよの気まぐれ日記

おぴよの気まぐれ日記

岡山やプログラミング、ファッションのこと、子育てや人生、生き方についての備忘録。

Ruby on Rails チュートリアルで30歳までに人生を変える(第5章)

こんにちは。opiyoです。

今回は、第5章をやっていきます。

第5章はレイアウト。つまり見た目の部分をメインにやっていきます。

では、早速始めてみたいと思います。

f:id:opiyotan:20170626134807p:plain

railsチュートリアル5章の学び

  • クラスとidの違い クラス:ページの中で何度でも使用ができる id:一度しか使用できない

  • 画像はapp/assets/imagesに置きimage_tag("ファイル名", alt: "属性名")で呼び出す

  • .(ドット)はクラスを表します

  • Atomエディタでのコメントアウト方法は「Commnad + /」

  • アセットディレクト

  • app/assets: 現在のアプリケーション固有のアセット
  • lib/assets: あなたの開発チームによって作成されたライブラリ用のアセット
  • vendor/assets: サードパーティのアセット

  • アセットをまとめる処理を行うのはSprocketsというgem

  • リダイレクトの場合のみ_url書式を使用

  • pathとurlの違い

  • 統合テスト (Integration Test)の実行方法

    • $ rails test:integration

railsチュートリアル5章の演習解説

5.1.1 演習 ナビゲーション

5.1.1.1

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

<回答>

$ curl -OL cdn.learnenough.com/kitten.jpg

5.1.1.2

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

<回答>

$ mv kitten.jpg app/assets/images/kitten.jpg

5.1.1.3

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

<回答>

# app/views/static_pages/home.html.erb
<div class="center jumbotron">
  <h1>Welcome to the Sample App</h1>

  <h2>
    This is the home page for the
    <a href="http://railstutorial.jp/">Ruby on Rails Tutorial</a>
    sample application.
  </h2>

  <%= link_to "Sign up now!", "#", class: "btn btn-lg btn-primary" %>
</div>

<%= link_to image_tag("rails.png", alt: "Rails logo"), "https://rubyonrails.org/" %>
<%= image_tag("kitten.jpg", alt: "cat logo") %>

5.1.2 演習 BootstrapとカスタムCSS

5.1.2.1

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

<回答>

<!-- <%= image_tag("kitten.jpg", alt: "cat logo") %> -->

5.1.2.2

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

<回答>

img {
  display: none;
}

5.1.3 演習 パーシャル(partial)

5.1.3.1

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

<回答>

# app/views/layouts/_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' %>

5.1.3.2

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

<回答> redになる!

5.1.3.3

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

<回答> greenになる!

5.2.2 演習 アセットパイプライン

5.2.2.1

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

<回答>

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $gray-medium-light;
  color: $gray-light;
  a {
    color: $gray;
    &:hover {
      color: $gray-darker;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 15px;
    }
  }
}

5.3.2 演習 RailsのルートURL

5.3.2.1

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

<回答>

 rails routes
 Prefix Verb URI Pattern        Controller#Action
   root GET  /                  static_pages#home
   help GET  /help(.:format)    static_pages#help
  about GET  /about(.:format)   static_pages#about
contact GET  /contact(.:format) static_pages#contact
rh0257:railstutorial_5 taku$ rails routes
 Prefix Verb URI Pattern        Controller#Action
   root GET  /                  static_pages#home
   helf GET  /help(.:format)    static_pages#help # 「helf」になっていることを確認!
  about GET  /about(.:format)   static_pages#about
contact GET  /contact(.:format) static_pages#contact

5.3.2.2

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

<回答> できた

5.3.2.3

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

<回答> Command + z

5.3.3 演習 名前付きルート

5.3.3.1

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

<回答> <%= link_to "Help", helf_path %>にしても/helpにジャンプすることを確認した

5.3.3.2

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

<回答> Command + z

演習 5.3.4 リンクのテスト

5.3.4.1

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

<回答>

$ rails test
Running via Spring preloader in process 49273
Started with run options --seed 21667

 FAIL["test_layout_links", SiteLayoutTest, 0.8195362979986385]
 test_layout_links#SiteLayoutTest (0.82s)
        Expected at least 1 element matching "a[href="/about"]", found 0..
        Expected 0 to be >= 1.
        test/integration/site_layout_test.rb:9:in `block in <class:SiteLayoutTest>'

  5/5: [============================================================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.95899s
5 tests, 12 assertions, 1 failures, 0 errors, 0 skips

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 <期待される値>, <実際の値>といった形で使っていましたが、内部では==演算子で期待される値と実際の値を比較し、正しいかどうかのテストをしています。

<回答>

# test/helpers/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

5.4.1 演習

5.4.1.1

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

<回答>

# routes.rb
  get '/signup', to: 'users#new'
# rails routesコマンド
$ rails routes
 Prefix Verb URI Pattern        Controller#Action
   root GET  /                  static_pages#home
   help GET  /help(.:format)    static_pages#help
  about GET  /about(.:format)   static_pages#about
contact GET  /contact(.:format) static_pages#contact
 signup GET  /signup(.:format)  users#new ← `signup`が追加されていることを確認!

5.4.1.2

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

<回答> OK

5.4.2 演習

5.4.2.1

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

<回答>

# rails testコマンド
$ rails test
Running via Spring preloader in process 2676
Started with run options --seed 22738

  7/7: [============================================================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.89370s
7 tests, 17 assertions, 0 failures, 0 errors, 0 skips

5.4.2.2

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

<回答> OK コメントアウト#で、元に戻すときはCommand + z

5.4.2.3

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

<回答>

# test/integration/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_template 'users/new' ← 追加!
  end
end