Help us understand the problem. What is going on with this article?

Rails Tutorial Memo #5

自分用の備忘録です.

第10章 ユーザーの更新・表示・削除

この章で学べること

  • これまで未実装だった edit,update,index,destroy アクションを加え,REST アクションを完成させる.
  • ユーザーが自分のプロフィールを自分で更新できるようにする.
  • すべてのユーザーを一覧できるようにする.
  • ユーザーを削除し,データベースから完全に消去する機能を追加する.

10.1 ユーザーを更新する

ユーザー情報を編集するパターンは新規ユーザーの作成と極めて似通っている.
newアクションと同じようにeditアクションを作成し,POST リクエストに応答するcreateアクションの代わりに PATCH リクエストに応答するupdateアクションを作成する.
ユーザーの登録は誰でも実行できるが,ユーザー情報を更新できるのはそのユーザー自身のみに限られる.

10.1.1 編集フォーム

ユーザー編集ページの正しい URL は/users/1/editであるため,ユーザーの id はparams[:id]で取り出すことができる.

Gravatarへのリンクでtarget="_blank"が使われているが,これを使うとリンク先を新しいタブ (またはウィンドウ) で開くようになるため,別のWebサイトへリンクするときなどに便利である(ただしtarget="_blank"にはセキュリティ上の小さな問題もある).

<a href="http://gravatar.com/emails" target="_blank">change</a>

一緒???

app/views/users/edit.html.erbform_for(@user)のコードは,app/views/users/new.html.erbform_for(@user)のコードと完全に同じ.

Rails はどうやって POST リクエストと PATCH リクエストを区別している?

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

Rails は@user.new_record?trueのときは POST を,falseのときは PATCH を使う.

target="_blank"の危険性

target="_blank"で新しいページを開くときには,セキュリティ上の小さな問題がある.それは,リンク先のサイトが HTML ドキュメントの window オブジェクトを扱えてしまう,という点である.具体的には,フィッシング (Phising) サイトのような,悪意のあるコンテンツを導入させられてしまう可能性がある.


対処法

リンク用の a タグの rel (relationship) 属性に、"noopener"と設定する

rel="noopener"の導入
<a href="http://gravatar.com/emails" target="_blank" rel="noopener">change</a>

10.1.2 編集の失敗

updateアクションはcreateアクションと極めて似通っている.updateアクションでは,update_attributesを使って,送信されたparamsに基づいてユーザーを更新する.無効な情報が送信されたときは,false が返される.

update_attributeへの呼び出しでuser_paramsを使っている.Strong Parametersを使うことで,マスアサインメントの脆弱性を防止している.

10.1.4 TDDで編集を成功させる

より快適にテストするためには,実装する前に統合テストを書いた方が便利.

passwordが空だと更新できない問題

allow_nil: trueをvalidatesに追加すると,パスワードやパスワード確認の欄を空にしてもユーザー情報を更新することができる.

10.2 認可

認証
サイトのユーザーを識別すること
認可
そのユーザーが実行可能な操作を管理すること

現時点では,どのユーザーもあらゆるアクションにアクセスできるため,だれでもユーザー情報を編集することができる.
ユーザーにログインを要求し,自分の情報しか編集できないようにする.

10.2.1 ユーザーにログインを要求する

beforeフィルター

何らかの処理が実行される直前に特定のメソッドを実行する仕組み

before_action :logged_in_user, only: [:edit, :update]
editアクションとupdateアクションを実行する前に,logged_in_userメソッドを実行しなさい」という意味.

10.2.3 フレンドリーフォワーディング

ログインしていないユーザーが編集ページにアクセスしようとしていたなら,そのユーザーがログインした後にはその編集ページにリダイレクトされるようにするのが望ましい.

ユーザーを希望のページに転送するには,リクエスト時点のページをどこかに保存しておき,その場所にリダイレクトさせる必要がある.

request オブジェクト

request.original_urlでリクエスト先が取得できる.

10.3.2 サンプルのユーザー

fakegem を使うと,サンプルのユーザーを大量に作ることができる.

10.3.3 ページネーション

1つのページに全てのユーザーを表示するのは好ましくない.ユーザー数が増加する可能性があるため.
これを解決するのがページネーション

will_paginategem は最もシンプルかつ堅牢なwill_paginateメソッドを使えるようにする gem である.

paginate メソッド

paginateでは,キーが:pageで値がページ番号のハッシュを引数に取る.
User.paginateは,:pageパラメーターに基いて,データベースからひとかたまりのデータ (デフォルトでは30) を取り出す.
1ページ目は1から30のユーザー,2ページ目は31から60のユーザーといった具合にデータが取り出される.pagenilの場合,paginateは単に最初のページを返す.

User.paginate(page: 1)  # 1 ~ 30 のユーザーを取得
User.paginate(page: 2)  # 31 ~ 60 のユーザーを取得

10.4 ユーザーを削除する

削除を実行できる管理(admin)ユーザーのクラスを作成する.

10.4.1 管理ユーザー

User モデルに,論理値をとる admin 属性を追加する.これを使って管理ユーザーかどうかを識別する.

Strong Parameters 再び

初期化ハッシュにadmin: trueを与えることによって,そのユーザーを権利者にすることができる.これ結構危ない.
例えば,攻撃者からPATCH users/17?admin=1というリクエストが送信された場合,17番目のユーザーを権利者に変えてしまう.こわぃ.

解決するためには,Strong Parameters を使えば良い.

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした