今回はプロゲートの上級3章、「ユーザー認証を仕上げよう」をやっていきます。
プロフィールの編集を制限しよう
下記の対応を行う。
- ユーザー一覧でログインユーザー(自分)のみ編集可能とする。
- 別ユーザーの編集ページにURL直で遷移できないようにする。
ユーザー一覧でログインユーザー(自分)のみ編集可能とする
ログインユーザーのみ編集ボタンを表示する。
users/show.html.erb
・ ・ <% if current_user.id == @user.id %> <div> <%= link_to '編集', edit_user_path(current_user.id)... %> </div> <% end %>
別ユーザーの編集ページにURL直で遷移できないようにする
users_controller.rb
class UsersController < ApplicationContoller # 編集画面表示、修正内容の更新アクション実行時はログインしているユーザーの場合のみ実行可とする。 before_action :correct_user, only: [:edit, :update] ・ ・ private def correct_user user = User.find(params[:id]) if current_user != user redirect_to root_path end end end
コントローラでヘルパーを使おう
Noteにも認証を追加しよう
NoteもUserと同様に自分が作成した投稿のみを編集できるように修正する。
notes_controller.rb
class NotesController < ApplicationController:Base before_action :correct_user, only: [:edit, :update] ・ ・ private def correct_user note = Note.find(params[:id]) # belong_toのおかげでnoteオブジェクトからuserオブジェクトへアクセスできる。 if current_user.id = note.user.id redirect_to root_path end end end
userとnoteは認証方法が全く同じなので、ヘルパーを定義し、DRYな実装にリファクタリングする。
ログインユーザー判定ヘルパーを作成する
ヘルパークラスがモジュールである理由
ヘルパーに定義した関数はコントローラー、viewへの機能追加の意味を持つ。
よってクラスへインクルードできるmoduleで定義する。
action_helper.rb
module ApplicationHelper def current_user?(user) current_user.id == user.id end end
自作ヘルパーのデフォルトスコープ
view: すべてのveiwで呼び出せる
controller: helperをinclude(機能追加)すれば呼び出し可能
ヘルパーのinclude
ヘルパーをインクルードする対象によって呼び出し可能なスコープが変化する。
〜Controller: 〜Controller内で呼び出し可能
ApplicationController: 全Controller内で呼び出し可能(ApplicationControllerは全Controllerで継承されているから)
アクションを移動しよう
ログイン後のみ、新規登録フォーム・投稿記事一覧を表示する対応を行う。
まず、トップ画面の表示コントローラーに新規登録と投稿記事一覧表示アクションを移動する。
移動対象のアクションは以下のnewとindex
notes_controller.rb
class NotesController < ・・・ ・ ・ def new @note = Note.new end def index @notes = Note.all end ・ ・ end
home_controller.rb.へ移動する。
class HomeController < ・・・ ・ ・ def top # deviseのログイン状態返却メソッドでログイン時のみ、Noteの情報を取得する if user_signed_in? @note = Note.new @notes = Note.all end end ・ ・ end
一覧を表示する順番を指定しよう
モデルより取得した情報を昇順、降順に並び替える。
Note.all.order(created_at: :desc) #作成日の降順で並び替え Note.all.order(created_at: :asc) #作成日の昇順で並び替え
orderの引数には、ハッシュの形でKeyに項目名、valueに並び替え方を設定する。
上記はcreated_at => :descを短く書く書き方
buildを使おう
Note生成時にログインユーザーのIDが自動設定されるように修正する。
記事投稿フォームからユーザーIDを削除する。
上記に伴い、作成アクションのstrongパラメータでユーザーIDを受け取らないように変更。
notes_controller.rb
class NotesController < ApplicationController def create @note = Note.new(note_params) ・ ・ end private def note_params params.require(:note).permit(:title, :content) # user_idを削除 end end
createメソッドでuser_idを設定する
class NotesController < ApplicationController def create # この時点ではuser_idは未設定 @note = Note.new(note_params) # user_idをログイン情報から取得し、user_idのsetterで設定する @note.user_id = current_user.id end end
buildを使ってuser_idを設定する
Note.newではuser_idは設定されないがbuildではuser_id(外部参照key)を自動セット。
class NotesController < ApplicationController def create # 以下は @note = Note.new(user_id: current_user.id)と同じ意味 @note = current_user.notes.build end end