getとpostで同じ名前のルーティングでもOK
以下のように、「/login」で2つのルーティングが同じ名前になっているが、getとpostでは異なるルーティングとして扱われるので問題ない。
:
get "login" => "users#login_form"
post "login" => "users#login"
:
<!-- link_toメソッドはデフォルトでgetのルーティングを探す -->
<%= link_to("ログイン", "/login") %>
<!-- form_tagメソッドはデフォルトでpostのルーティングを探す -->
<%= form_tag("/login") do %>
:
<% end %>
変数session
ページを移動してもユーザーの情報を保持し続けるために使われる。
sessionに代入された値は、ブラウザに保存される。
session[:キー名] = 値
で値がブラウザに保存される。
def login
@user = User.find_by(...)
if @user
# 特定したユーザーのidを代入し、ログインユーザーの情報を保持
session[:user_id] = @user.id
:
end
:
end
def logout
# nilを代入することで、値を空の状態にできる(ログイン状態ではなくすることができる)
session[:user_id] = nil
end
※sessionの値を変更する場合は、ルーティングはpostになることに注意
:
post "logout" => "users#logout"
:
before_action
○before_actionが必要になる場面
top.html.erbやabout.html.erbなどの各アクションに対応したビューファイルは、applecation.html.erbの<%= yield %>
部分に代入される。
これによって、application.html.erbは全アクションから呼び出される。
つまり、application.html.erbでアクション側の変数を使おうとすると、以下のように全アクションで@変数を定義しなければいけなくなる。
def index
@current_user = User.find_by(id: session[:user_id])
end
def show
@current_user = User.find_by(id: session[:user_id])
end
def new
@current_user = User.find_by(id: session[:user_id])
end
:
このように、各コントローラーの全アクションで共通する部分はbefore_action
を使う。
before_action
を用いることで、アクションが呼び出される際に必ずbefore_action
の処理が先に実行される。
# before_action 全アクションで共通する処理
before_action :set_current_user
def set_current_user
@current_user = User.find_by(id: session[:user_id])
end
def index
# @current_user = User.find_by(id: session[:user_id])
end
def show
# @current_user = User.find_by(id: session[:user_id])
end
def new
# @current_user = User.find_by(id: session[:user_id])
end
:
applicationコントローラー
全てのコントローラーで共通する処理はapplicationコントローラーにまとめる。
before_action :set_current_user
def set_current_user
@current_user = User.find_by(id: session[:user_id])
end
before_actionを特定のアクションのみで実行
before_actionにonly
を用いることで、before_actionで指定したメソッドをonly
で指定したアクションでのみ実行させることができる。
before_action :authenticate_user, {only: [:edit, :update]}
def authenticate_user
:
end
class UsersController < ApplicationController
# applicationコントローラーを継承しているので、継承元のメソッドを使うことができる
before_action :authenticate_user
:
end
to_iメソッド
to_iメソッド
は文字列を数値に変換することができる。
before_action :ensure_correct_user, {only: [:edit, :update]}
def endure_correct_user
# params[:id]で取得できるのは数字であっても文字列なのでto_iメソッドで数値に変換する
if @current_user.id != params[:id].to_i
flash[:notice] = "権限がありません"
redirect_to("/posts/index")
end
end