これから作っていく簡単なWebアプリの作成メモ(自分の備忘)です。
自分用なのであまり凝りすぎないように書いていきたい。
##今回やったこと
今回はユーザーがログインできるようにしたい。
以下の記事で詳細な説明をしていたのでぜひ紹介したい。
【Rails】ログイン機能を実装する
上記の記事を大いに参考にさせていただきます。
bcryptは導入済み、User.rbにもhash_secure_password
を追加済みなので、セッションを利用したユーザー管理ができるようにする。
Sessionsコントローラーを作成する。
$ rails g controller Sessions new
ルーティングを作成しておく。
(略)
# Sessions
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
(略)
各種の処理と画面を作成する。
まずは画面寄りの部分。
$ touch ./app/views/sessions.new.html.erb
<h1>ログイン</h1>
<%= form_for(:session, url: login_path) do |f| %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Log in" %>
<% end %>
(略)
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<% if logged_in? %>
<a class="dropdown-item" href="<%= root_path %>">ホーム</a>
<a class="dropdown-item" href="<%= schedules_path %>">予定</a>
<a class="dropdown-item" href="<%= users_path %>">ユーザー</a>
<a class="dropdown-item" href="<%= logout_path %>" data-method="delete">ログアウト</a>
<% else %>
<a class="dropdown-item" href="<%= login_path %>">ログイン</a>
<% end %>
</div>
(略)
※aタグでdeleteのリクエストを送信するためにdata-method
属性を設定しているが、以下の記事を参考にした。
[Rails]aタグでも「data-method="delete"」を設定すればlink_toと同じ挙動
link_toで突然methodが効かなくなって困ってるあなたへ
次に内部処理寄りの部分。
まずはヘルパーから。
module SessionsHelper
# 渡されたユーザーでログインする
def log_in(user)
session[:user_id] = user.id
end
# 現在ログイン中のユーザーを返す (いる場合)
def current_user
if session[:user_id]
#@current_user = @current_user || User.find_by(id: session[:user_id])と同じ意味
@current_user ||= User.find_by(id: session[:user_id])
end
end
#受け取ったユーザーがログイン中のユーザーと一致すればtrueを返す
def current_user?(user)
user == current_user
end
# ユーザーがログインしていればtrue、その他ならfalseを返す
def logged_in?
!current_user.nil?
end
# 現在のユーザーをログアウトする
def log_out
session.delete(:user_id)
@current_user = nil
end
end
次にコントローラーの処理。
class ApplicationController < ActionController::Base
include SessionsHelper
end
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to root_url
else
render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_url
end
end
また、ログインしていないユーザーをログインページにリダイレクトするアクションを作成。
class ApplicationController < ActionController::Base
include SessionsHelper
private
# ログイン済みユーザーかどうか確認
def logged_in_user
unless logged_in?
redirect_to login_url
end
end
end
logged_in_user
をスケジュールとユーザーのコントローラーのbefore処理として記述。
class SchedulesController < ApplicationController
before_action :logged_in_user
(略)
class UsersController < ApplicationController
before_action :logged_in_user
(略)
以上で参考記事をもとにしたログイン処理の追加が完了した。
あとは、ログイン画面がプロトなので(以下添付画像のような見た目)、
これを以下のように手を加えた。
<h1>ログイン</h1>
<%= form_for(:session, url: login_path, html: {class: "form-signin"}) do |f| %>
<div class="form-label-group my-3">
<%= f.label :email %>
<%= f.email_field :email, class: "form-control", placeholder: "Eメールアドレス" %>
</div>
<div class="form-label-group my-3">
<%= f.label :password %>
<%= f.password_field :password, class: "form-control", placeholder: "パスワード" %>
</div>
<div class="d-grid gap-2">
<%= f.submit "ログイン", class: "btn btn-lg btn-primary my-3" %>
</div>
<% end %>
こうすると、以下のようにログイン画面が表示される。
結構進んだ。
まだログイン失敗時も含め、方々のエラーメッセージ表示ができないが、今回はここまで。