第5章Railsチュートリアル演習問題と解答まとめ

Ruby on Railsチュートリアルの演習問題と解答をまとめる。

第5章 レイアウトを作成する - Railsチュートリアル

f:id:yukitoku_sw:20191019165508p:plain

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


演習5.1.1 ナビゲーション

問題1

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

解答

リスト5.4のコードを実行する

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


問題2

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

解答

さっきダウンロードしたネコ画像はカレントディレクトリにあるので
rails.pngと同じapp/assets/images/に移動させる

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


問題3

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

解答

[app/views/static_pages/home.html.erb]

<div class="center jumbotron">
  (中略)
</div>

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


演習5.1.2 BootstrapとカスタムCSS

問題1

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

解答

[app/views/static_pages/home.html.erb]
<div class="center jumbotron">
  (中略)
</div>

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

f:id:yukitoku_sw:20191021110310p:plain


問題2

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

解答

custom.scssにリスト5.11を追加

f:id:yukitoku_sw:20191021111513p:plain


演習5.1.3 パーシャル(partial)

問題1

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

解答

[app/views/layouts/application.html.erb]
リスト5.18参照
[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' %>  


問題2

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

解答

先にパーシャルを作ってしまったため、テストはGREEN。。

問題3

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

解答

動作確認ok


演習5.2.2 素晴らしい構文を備えたスタイルシート

問題1

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

解答

リスト5.20参照


演習5.3.2 RailsのルートURL

問題1

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

解答

リスト5.29参照

$ rails routes で確認してみる

$ rails routes
 Prefix Verb URI Pattern        Controller#Action
   root GET  /                  static_pages#home
   helf GET  /help(.:format)    static_pages#help
  about GET  /about(.:format)   static_pages#about
contact GET  /contact(.:format) static_pages#contact

helpの名前付きルートがhelfに変わっている


問題2

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

解答

$ rails test

NameError:         NameError: undefined local variable or method `help_path' for ...  

ネームエラーとなるので、先ほどのas: helf を消す。とテストが通る。


問題3

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

解答

動作確認のため省略


演習5.3.3 名前付きルート

問題1

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

解答

helfルーティングの作成はリスト5.29参照

[app/views/layouts/_header.html.erb]

<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", root_path, id: "logo" %>
    <nav>
      <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>
    </nav>
  </div>
</header>


問題2

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

解答

動作確認のため省略


演習5.3.4 リンクのテスト

問題1

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

解答

contact_pathへ変更

[app/views/layouts/_footer.html.erb]

<footer class="footer">
  (中略)
  <nav>
    <ul>
      <li><%= link_to "About", contact_path %></li>
      <li><%= link_to "Contact", contact_path %></li>
      <li><a href="http://news.railstutorial.org/">News</a></li>
    </ul>
  </nav>
</footer>

テスト

$ rails test
(中略)
 FAIL["test_layout_links", SiteLayoutTest, 0.43844699999317527]
 test_layout_links#SiteLayoutTest (0.44s)
        Expected at least 1 element matching "a[href="/about"]", found 0..
        Expected 0 to be >= 1.
        test/integration/site_layout_test.rb:10:in `block in <class:SiteLayoutTest>'

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

Finished in 0.52657s
6 tests, 13 assertions, 1 failures, 0 errors, 0 skips

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

解答

test_helper.rb リスト5.35参照
site_layout_test.rb リスト5.36参照

[test/helpers/application_helper_test.rb]

require 'test_helper'

class ApplicationTest < 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 Usersコントローラ

問題1

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

解答

users_new_urlをsignup_pathに修正する

[test/controllers/users_controller_test.rb]

require 'test_helper'

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

end

テストを実行すると、NameErrorとなるのでroutesファイルを修正する。

[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'
  get '/signup',  to: 'users#new'
end


問題2

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

解答

問題1で行ったので省略


演習5.4.2 ユーザー登録用URL

問題1

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

解答

テストの結果がGREEN になっていることを確認


問題2

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

解答

動作を確認


問題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
    assert_select "a[href=?]", signup_path
    get contact_path
    assert_select "title", full_title("Contact")
    get signup_path
    assert_select "title", full_title("Sign up")
  end
end


ちゃんちゃん


yukitoku-sw.hatenablog.com