Ruby on Railsチュートリアル第5章
第5章(レイアウトを作成する)
Bootstrapやcss関連のところは、飛ばしながらコピペでいきます。
ナビゲーション
link_toメソッド
link_to
メソッドはHTMLのaタグを生成する。- 第1引数としてリンクテキスト、第2引数としてURL(名前付きルーティング)を取る。
<li><%= link_to "Home", '#' %></li>
は、<li><a href="#">Home</a></li>
を返す。
image_tag
image_tag
ヘルパーは、シンボルを使用してalt属性やwidth属性を設定可能。- ソースには、完全なパス、もしくは
app/assets/images
ディレクトリ配下のファイルを指定可能。
例えば、以下のように記述されたERBは
<%= link_to image_tag("rails.svg", alt: "Rails logo", width: "200"), "https://rubyonrails.org/" %>
以下のHTMLが返される。
<img alt="Rails logo" width="200px" src="/assets/rails-<long string>.svg">
- Railsはassetsディレクトリ直下の画像を
app/assets/images
ディレクトリと紐づけるため、src属性にimageディレクトリは不要。 はファイル名が一意になるようにRailsが追加したもの。
パーシャル
- ビューの重複する記述に関してはパーシャルにまとめる。
- パーシャルはディレクトリ内で一目見ただけでわかるように、ファイル名の先頭にアンダースコア「_」を付す。
- パーシャルの呼出しには
<%= render 'layouts/header' %>
のような形でrenderヘルパーで呼び出す。この際に探すファイル名はapp/views/layouts/_header.html.erb
となる。
アセットパイプライン
アセットパイプラインはJavaScriptやCSSの連結圧縮するフレームワークで、重要な部分なのでまとめておきます。
- アセットディレクトリ、マニフェストファイル、プリプロセッサエンジンの3つが主要な機能。
- アセットディレクトリには、静的ファイルを目的別に分類する3つのディレクトリがある。(固有、ライブラリ用、サードパーティー用)
- マニフェストファイルは、アセットディレクトリに配置されたファイルをまとめる指示書。Sprockets gemによっておこなわれる。
- プリプロセッサエンジンは拡張子に合わせてプリプロセス(前処理)を実行し結合することで、ブラウザへ配信可能な形とする。
- アセットパイプラインの機能は、SPAとも組み合わせることがUX向上に非常に有効。
レイアウトのリンク
名前付きルーティング
ERBテンプレートに記述するリンクは
<a href="/static_pages/about">About</a>
のように、素のHTMLを記述可能であるがRails流では無い。
URLは/static_pages/about
よりも/about
の方がよく、ERBの名前付きルーティングを使用するのが慣習。
<%= link_to "About", about_path %>
ルーティングの記述
- root_pathはルートURL以下の文字列「'/'」を返す。
- root_urlは完全なURLの文字列「'https://www.example.com/'」を返す。
- 基本的にはpath書式を使用し、リダイレクト時のみurl書式を使用するのが慣習。
- これまでの
get "static_pages/help"
のような記述は、get "/help", to: "static_pages#help"
とする。これによって、/helpページをGETリクエストされた際に、helpアクションを呼び出す。更に名前付きルーティングも使用できるようになる。
統合テスト
統合テストに入ります。ここでは、上記のルーティングのテストをおこないます。
まずは、テストテンプレートを生成。
$ rails generate integration_test site_layout
テストの手順の通りに書いてみる。
1. ルートURL(Homeページ)にGETリクエストを送る。
2. 正しいページテンプレートが描画されているかどうか確かめる。
3. Home、Help、About、Contactの各ページへのリンクが正しく動くか確かめる。
[test/integration/site_layout_test.rb] require "test_helper" class SiteLayoutTest < ActionDispatch::IntegrationTest test "layout links" do get root_path #ルートURLへアクセス。 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 end end
ユーザー登録の実装
rails generate
でコントローラを作成する。ユーザー登録はRESTに従いnewアクションを指定。
$ rails generate controller Users new
後は、サインアップ用にルーティングの設定、サインアップ用ボタンへのリンク追加、サインアップページを作成したら最初のステップは完了。
開発環境が動かなくなったとき
- 以下のコマンドを実行する。
$ bundle exec rails app:update:bin
git status
でファイルに変更が生じているかどうかを確認。- 変更が生じていたら、
git commit -am "Update bin files"
を実行。 - 再度
git push
これで復活出来ることがあるらしいです。
第5章ー演習ー
5.1.1
飛ばします。
5.1.2
飛ばします。
5.1.3
①Railsがデフォルトで生成するheadタグの部分を、リスト 5.17のようにrenderに置き換えてみてください。(ヒント: 単純に削除してしまうと後でパーシャルを1から書き直す必要が出てくるので、削除する前にどこかに退避しておきましょう。)
(解答)
[app/views/layouts/application.html.erb] <!DOCTYPE html> <html> <head> <title><%= full_title(yield(:title)) %></title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="utf-8"> <%= render 'layouts/rails_default' %> </head> <body> <%= render 'layouts/header' %> <div class="container"> <%= yield %> <%= render 'layouts/footer' %> </div> </body> </html>
②リスト 5.17のようなパーシャルはまだ作っていないので、現時点ではテストは red になっているはずです。実際にテストを実行して確認してみましょう。
(解答) テストREDになる。
③layoutsディレクトリにheadタグ用のパーシャルを作成し、先ほど退避しておいたコードを書き込み、最後にテストが green に戻ることを確認しましょう。
(解答) パーシャルを追加したらGREENになった。
[app/views/layouts/_rails_default.html.erb] <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
5.2.2
飛ばします。
5.3.2
確認だけなので飛ばします。
5.3.3
確認だけなので飛ばします。
5.3.4
①footerパーシャルのabout_pathをcontact_pathに変更してみて、テストが正しくエラーを捕まえてくれるかどうか確認してみてください。
(解答) ちゃんとaboutリンクが無いとエラーが出た。
FAIL SiteLayoutTest#test_ルートURLのリンクテスト (1.78s) 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>'
②リスト 5.34で示すように、Applicationヘルパーで使っているfull_titleヘルパーを、test環境でも使えるようにすると便利です。こうしておくと、リスト 5.35のようなコードを使って、正しいタイトルをテストすることができます。ただし、これは完璧なテストではありません。例えばベースタイトルに「Ruby on Rails Tutoial」といった誤字があったとしても、このテストでは発見することができないでしょう。この問題を解決するためには、full_titleヘルパーに対するテストを書く必要があります。そこで、Applicationヘルパーをテストするファイルを作成し、リスト 5.36の(コードを書き込む)の部分を適切なコードに置き換えてみてください。(ヒント: リスト 5.36ではassert_equal <期待される値>, <実際の値>といった形で使っていましたが、内部では==演算子で期待される値と実際の値を比較し、正しいかどうかのテストをしています。)
(解答) タイトルヘルパーが正しいことの単体テスト。
[test/helpers/application_helper_test.rb] require "test_helper" class ApplicationHelperTest < ActionView::TestCase test "full title helper" do assert_equal 'Ruby on Rails Tutorial Sample App', full_title assert_equal 'Help | Ruby on Rails Tutorial Sample App', full_title("Help") end end
5.4.1
①表 5.1を参考にしながらリスト 5.40を変更し、users_new_urlではなくsignup_pathを使えるようにしてみてください。
(解答)
[test/controllers/users_controller_test.rb] class UsersControllerTest < ActionDispatch::IntegrationTest test "should get new" do get signup_path assert_response :success end end
②先ほどの変更を加えたことにより、テストが red になったことを確認してください。なお、この演習はテスト駆動開発(コラム 3.3)で説明した red / green のリズムを作ることを目的としています。このテストは次の5.4.2で green になるよう修正します。
(解答) nameエラーとなった。
ERROR UsersControllerTest#test_should_get_new (0.15s) Minitest::UnexpectedError: NameError: undefined local variable or method `signup_path' for #<UsersControllerTest:0x00007f9df09e5af8> test/controllers/users_controller_test.rb:5:in `block in <class:UsersControllerTest>'
5.4.2
①もしまだ5.4.1.1の演習に取り掛かっていなければ、まずはリスト 5.40のように変更し、名前付きルーティングsignup_pathを使えるようにしてください。また、リスト 5.42で名前付きルーティングが使えるようになったので、現時点でテストが green になっていることを確認してください。
(解答) GREENになっている。
②先ほどのテストが正しく動いていることを確認するため、signupルートの部分をコメントアウトし、テスト red になることを確認してください。確認できたら、コメントアウトを解除して green の状態に戻してください。
(解答) ルーティングをコメントアウトしたら以下のエラー。解除したらGREEN。
ERROR UsersControllerTest#test_should_get_new (0.13s) Minitest::UnexpectedError: NameError: undefined local variable or method `signup_path' for #<UsersControllerTest:0x00007f0062b8b758> test/controllers/users_controller_test.rb:5:in `block in <class:UsersControllerTest>'
③リスト 5.31の統合テストにsignupページにアクセスするコードを追加してください(getメソッドを使います)。コードを追加したら実際にテストを実行し、結果が正しいことを確認してください。(ヒント: リスト 5.35で紹介したfull_titleヘルパーを使ってみてください。)
(解答)
[test/integration/site_layout_test.rb] test "signup path layout links" do get signup_path #サインアップへアクセス。 assert_template 'users/new' #指定のレイアウトが表示されるか 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 "title", full_title("Sign up") #タイトルが正しいか end
第5章ーまとめー
- ビューの重複するファイルはパーシャルにまとめ、パーシャルはパーシャルであると認識出来るようにファイル名にアンダースコアを付ける。
- アセットパイプラインはJacaScriptやCSSを結合圧縮し、ページの表示速度を向上させる重要な機能。
- レイアウトのリンクは名前付きルーティングを使えるような形にする。
- 統合テストでは、複数の機能が連動するような場面で活用する。
第5章終わり🐻