##ログイン機能
###ログインページを作る
まず、ルーティングとコントローラを設定する。
usersコントローラのlogin_formアクションを定義する。
get "login" => "users/login_form"
def login_form
end
ビューでログインフォームを表示する。
<p>メールアドレス</p>
<input name="email" value="<%= @email %>">
<p>パスワード</p>
<input type="password" name="password" value="<%= @password %>">
<input type="submit" value="ログイン">
###フィームの送信
次に、フォームのあたいを送信できるようにloginアクションを作る。
post "login" => "users/login"
def login
end
ログインフォームの方もform_tagを追加しておく。
#/loginへフォームの値を送信
<%= form_tag("/login") do %>
<p>メールアドレス</p>
<input name="email" value="<%= @email %>">
<p>パスワード</p>
<input type="password" name="password" value="<%= @password %>">
<input type="submit" value="ログイン">
<% end %>
また/loginで被っているが、post,getで異なったルーティングと認識されるので問題ない。
##ユーザーを特定
loginアクションで、ユーザーを特定する処理をする。
情報が一致した場合はフラッシュメッセージとともに投稿一覧へ。
しなかった場合はエラーメッセージとともにログインフォームへ、初期値として入力済みのもの。
def login
#ログインフォームで入力されたものが、データベースの情報とあっているか確認する
@user = User.find_by(email: params[:email], password: params[:password])
if @user
flash[:notice] = "ログインしました"
redirect_to("/posts/index")
else
@error_message = "メールアドレスまたはパスワードが間違っています"
@email = params[:email]
@password = params[:password]
render("users/login_form")
end
end
##session変数
ページを移動してもユーザー情報を保持するためにsession関数を使う。
session[:キー] = 値
と記述をする。
今回は、ログインに成功した時にユーザー情報を保持しts保持したいので、loginアクションを追加修正する。
def login
#ログインフォームで入力されたものが、データベースの情報とあっているか確認する
@user = User.find_by(email: params[:email], password: params[:password])
if @user
session[:user_id] = @user.id
...
end
また新規登録時にそのままログイン状態にして、セッション変数で情報を保持する。
def create
@user = User.new(
name: params[:name],
email: params[:email],
image_name: "default_user.jpg",
password: params[:password]
)
if @user.save
#新規登録に成功すれば、ログイン状態にする
session[:user_id] = @user.id
flash[:notice] = "ユーザー登録が完了しました"
redirect_to("/users/#{@user.id}")
else
render("users/new")
end
end
##ログアウト機能
ログアウトする場合はセッションの値をからにする。
セッションの値を変更するときはpostとする。
post "logout" => "users#logout"
def logout
session[:user_id] = nil
flash[:notice] = "ログアウトしました。"
redirect_to("/login")
end
##ログイン中のユーザーを取得する
###before_action
各コントローラの全アクションで共通の処理がある場合に使う。
ユーザー情報は全アクションで使うためapplication_controller.rb で処理を書いておく。
ここでは、set_crrent_userメソッドを定義する。
before_action :set_current_user
def set_current_user
@current_user = User.find_by(id: session[:user_id])
end
##アクセス制限
###ログインしていない場合
ログインが必要なページを表示しようとした場合は、フラッシュメッセージとともにログインページに移動する、authenticate_userメソッドを作る。
def authenticate_user
#ユーザー情報がない場合
if @current_user == nil
flash[:notice] = "ログインが必要です"
redirect_to("/login")
end
end
onlyを用いて、指定したアクションのみでメソッドを実行する。
before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
before_action :authenticate_user
###ログインしている場合
ログインしている場合も同様に、アクセス制限のメソッドを作っておく。
def forbid_login_user
if @current_user
flash[:notice] = "すでにログインしています"
redirect_to("/posts/index")
end
end
対応するアクションに対してメソッドを適応させる。
before_action :forbid_login_user,{only: [:top]}
before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
##ユーザー編集の制限
自分以外のユーザーの編集をできないように制限をかける。
#詳細ページのユーザーidとログインユーザーidが一致している場合は編集ok
<% if @user.id == @current_user.id %>
<%! linl_to("編集","users/#{@user.id}/edit") %>
<% end %>
次にアクションの方でも制限しておく。
ensure_correct_userアクションを用いる。
ログインしているユーザーと編集したいユーザーが等しくないとき、投稿一覧ページへとリダイレクトさせる。
before_action :ensure_correct_user, {only: [:edit,:update]}
def ensure_correct_user
if @current_user.id != params[:id].to_i
flash[:notice] = "権限がありません。"
redirect_to("/posts/index")
end
end
###to_iメソッド
params[:id]で帰ってくる数値は文字列になっているため、to_iメソッドを使うことによって、数値としてidを取得できる。
続き
https://qiita.com/jonnyjonnyj1397/items/dbc91ac83aea40e868ef