Ruby on Railsチュートリアルの演習問題と解答をまとめる。
アウトプットすることで、より自分の理解を深めることを目的としています。
自分なりに調べて考えた回答のため、記載内容に誤りがある場合はコメントいただけると幸いです。
- 演習5.1.1 ナビゲーション
- 演習5.1.2 BootstrapとカスタムCSS
- 演習5.1.3 パーシャル(partial)
- 演習5.2.2 素晴らしい構文を備えたスタイルシート
- 演習5.3.2 RailsのルートURL
- 演習5.3.3 名前付きルート
- 演習5.3.4 リンクのテスト
- 演習5.4.1 Usersコントローラ
- 演習5.4.2 ユーザー登録用URL
演習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 "), '#' %>
問題2
リスト 5.11のコードをcustom.scssに追加し、すべての画像を非表示にしてみてください。うまくいけば、Railsのロゴ画像がHomeページから消えるはずです。先ほどと同様にインスペクタ機能を使って、今度はHTMLのソースコードは残ったままで、画像だけが表示されなくなっていることを確認してみてください。
解答
custom.scssにリスト5.11を追加
演習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
ちゃんちゃん