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

10章でやること
ユーザーの更新・表示・削除
→未実装のedit、update、index、destroyアクションを加えてRESTアクションを完成させる

  • ユーザーが自身でプロフィールを更新できるようにする
  • ログイン済の場合ユーザー一覧を表示できるようにする
  • 管理ユーザーを作成し、管理ユーザーのみユーザーを削除できるようにする

10.1 ユーザーを更新する

ユーザー情報を編集するパターンは新規ユーザーの作成を参考に進められる

新規ユーザー用のビューを出力するnewアクションと同じようにして、ユーザーを編集するためのeditアクションを作成すればよいのです。同様に、POSTリクエストに応答するcreateの代わりに、PATCHリクエストに応答するupdateアクションを作成します

ただし、ユーザー登録は誰でもできるけどユーザー情報の更新はそのユーザー自身に限られる!
→8章の承認機構を使ってアクセスを制御する
ブランチを切って作業開始ー

10.1.1 編集フォーム

見本はRoRT本文
まずはUsersコントローラーにeditアクションを追加、それに対応するeditビューを実装する

ここではデータベースから適切なユーザーデータを読み込む必要があります。ここで注意して頂きたいのは、表 7.1ではユーザー編集ページの正しいURLが/users/1/editとなっていることです (ユーザーのidが1の場合)。ユーザーのidはparams[:id]変数で取り出すことができるのを思い出してください

コードはこうなる

ビューも作る(ファイルは手動で作る)

リスト 7.15
のUsers/newのビューと重複している部分が多い→重複部分をパーシャルにまとめられる→演習でやるよ!

target=”_blank”

Gravatarへのリンクでtarget=”_blank”が使われている
リンク先を新しいタブ(もしくはウィンドウ)で開くタグだけど、セキュリティ上の問題がある。→演習でやるよ

レンダリングされたページを見ていく

@userインスタンス変数を使うことで”Name”や”Email”の部分に自動的に値が入力される。
→Railsによって@user変数の属性情報から引き出されている

value=”patch”

WebブラウザはネイティブではPATCHリクエスト (表 7.1でRESTの慣習として要求されている) を送信できないので、RailsはPOSTリクエストと隠しinputフィールドを利用してPATCHリクエストを「偽造」しています。

どういうことだってばよ🤔
→本文曰く詳細を気にする必要はないということなので、もうちょっと強くなったころに考えてみたりするかもしれません

POSTリクエストとPATCHリクエスト

上記のform_for(@user)のコードはユーザー登録フォームのコードと完全に一致
→ではRailsはどうやってPOSTリクエストとPATCHリクエストを区別しているのか

Railsは、ユーザーが新規なのか、それともデータベースに存在する既存のユーザーであるかを、Active Recordのnew_record?論理値メソッドを使って区別できるからです。

trueのときにはPOSTを、falseのときにはPATCHを使う用にRailsが判断してくれる。

ところでform_forはform_withになったのでは?
→form_withでも同様に処理されるようです

ナビゲーションバーの更新

パーシャルの_header.html.erbを編集してユーザー設定リンクを有効にする

演習

  1. 先ほど触れたように、target=”_blank”で新しいページを開くときには、セキュリティ上の小さな問題があります。それは、リンク先のサイトがHTMLドキュメントのwindowオブジェクトを扱えてしまう、という点です。具体的には、フィッシング (Phising) サイトのような、悪意のあるコンテンツを導入させられてしまう可能性があります。Gravatarのような著名なサイトではこのような事態は起こらないと思いますが、念のため、このセキュリティ上のリスクも排除しておきましょう。対処方法は、リンク用のaタグのrel (relationship) 属性に、”noopener”と設定するだけです。早速、リスト 10.2で使ったGravatarの編集ページへのリンクにこの設定をしてみましょう。
  2. リスト 10.5のパーシャルを使って、new.html.erbビュー (リスト 10.6) とedit.html.erbビュー (リスト 10.7) をリファクタリングしてみましょう (コードの重複を取り除いてみましょう)。ヒント: 3.4.3で使ったprovideメソッドを使うと、重複を取り除けます3。(関連するリスト 7.27の演習課題を既に解いている場合、この演習課題をうまく解けない可能性があります。うまく解けない場合は、既存のコードのどこに差異があるのか考えながらこの課題に取り組んでみましょう。例えば筆者であれば、リスト 10.5で用いた変数を渡すテクニックを使って、リスト 10.6やリスト 10.7で必要になるURLをリスト 10.5に渡してみるでしょう。)

1.

2.
/sample_app/app/views/users/に_form.html.erbを作る
new.html.erbとedit.html.erbを修正
ハイライト部分は本文から変更有の箇所

現状ではupdateアクションを作っていないのでユーザー情報更新のボタンを押してもエラーで動かないし
テストも書いてないのでエラーのキャッチもされません!

(あれ?あれ?って嵌ってたのは内緒だよ!)

provideメソッド→renderメソッド

provideメソッドを使って値を渡している部分をrenderメソッドでも渡せるそうなので後で試してみる気持ち。

10.1.2 編集の失敗

updateアクションを作成する!
createアクションと同様に、無効な情報が送られた場合falseが返されてelseに分岐し編集ページをレンダリングする
↑これを実装すると↓こうなる

update_attributesへの呼び出しでuser_paramsを使っていることに注目してください。7.3.2でも説明したように、ここではStrong Parametersを使ってマスアサインメントの脆弱性を防止しています。

Userモデルのバリデーションとエラーメッセージのパーシャルが既にあるので (リスト 10.2)、無効な情報を送信すると役立つエラーメッセージが表示されるようになっています (図 10.3)。

演習

動作確認のみにて省略

10.1.3 編集失敗時のテスト

フォーム失敗時の実装をしたのでテストを書いていく!
↓統合テストを生成

  1. 編集ページにアクセス時editビューが描画されるか
  2. 無効な情報を送信するとeditビューが再描画されるか

PATCHリクエストを送るためにpatchメソッドを使っていることに注目してください。これはgetやpost、deleteメソッドと同じように、HTTPリクエストを送信するためのメソッドです。

ptchメソッドなど、RESTアーキテクチャについて→RoRT本文

演習

  1. リスト 10.9のテストに1行追加し、正しい数のエラーメッセージが表示されているかテストしてみましょう。ヒント: 表 5.2で紹介したassert_selectを使ってalertクラスのdivタグを探しだし、「The form contains 4 errors.」というテキストを精査してみましょう。

※文章は日本語にしているので上記だけど本文に合わせるならこう↓

10.1.4 TDDで編集を成功させる

画像の変更は外部サービス(Gravatar)に任せているのでそれ以外の機能を実装していく!

アプリケーション用のコードを「実装する前に」統合テストを書いた方が便利だと気付いた読者もいるかもしれません。実際、そういったテストのことは「受け入れテスト (Acceptance Tests)」として呼ばれていて、ある機能の実装が完了し、受け入れ可能な状態になったかどうかを決めるテストとして知られています。

ユーザー情報編集の成功に対するテスト

  1. ユーザー情報を更新
  2. flashメッセージが空でないか
  3. プロフィールページにリダイレクトされるか
  4. データベース内のユーザー情報が正しく変更されたか

パスワードが空っぽ

パスワードを変更する必要がない場合はパスワードを入力せずに更新できると便利
→便利だけどいいのかな?とも思う

テストが書けたら

updateアクションを実装する

現状ではテストはまだRED
→パスワードに対するバリデーションに引っかかるため

テストが greenになるためには、パスワードのバリデーションに対して、空だったときの例外処理を加える必要があります。

allow_nil: true

対象の値がnilの場合バリデーションをスキップする為のオプション


これをバリデーションに追加する

→ユーザー編集ページ動くようになりました✨

検証

  1. 実際に編集が成功するかどうか、有効な情報を送信して確かめてみましょう。
  2. もしGravatarと紐付いていない適当なメールアドレス (foobar@example.comなど) に変更した場合、プロフィール画像はどのように表示されるでしょうか? 実際に編集フォームからメールアドレスを変更して、確認してみましょう。

1.動作確認のみにて省略
2.Gravatarの初期画像が表示される(未登録扱い?)

まとめとか感想

過去の分の理解が足りてなかったり、注意力が足りてなかったりで余分にはまっちゃった感あるんだけど
余分な分は無駄じゃなくて積み重ねということでヒトツ!

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

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

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