プログラミングの勉強日記
2020年7月18日 Progate Lv.211
Ruby on RailsⅧ
ログインページの作成
ログインするためにはログインページからメールアドレスやパスワードなどの情報をRaisに送信する。送信された情報をもとに操作しているユーザを特定しログイン状態とする。ログインページを作るためにルーティング、アクション、ビューを追加する。
get "login" => "users#login_form"
def login_form
end
<input>
タグのtype属性をpasswordとすると入力した文字が伏字となるパスワード用のフォームになる。
<p>パスワード</p>
<input type="password">
パスワードカラムの追加
rails generate migration
を用いてadd_password_to_users
というファイル名のマイグレーションファイルを作成する。
$ rails generate add_password_to_users
マイグレーションを変更後
$ rails db:migrate
class AddPasswordToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password, :string
end
end
ユーザの情報には必ずパスワードが存在してほしいので、バリデーションをかける。
class User < ApplicationRecord
validates :password, {presence: true}
end
ユーザの特定
フォームに入力されたメールアドレスとパスワードは、params[:email]
とparams[:password]
で受け取れる。usersテーブルから入力された値に一致するユーザを取得し、変数@userに代入する。フォームから送信されたメールアドレスとパスワードに一致するユーザが存在する場合はフラッシュメッセージを表示し、投稿一覧ページにリダイレクトする。ユーザが存在しない場合はログインページを再表示する。
def login
@user=User.find_by(email: params[:email], password: params[:password])
#ユーザが存在する場合の処理
if @user
flash[:notice]="ログイン成功"
redirect_to("/posts/index")
#ユーザが存在しない場合
else
render("users/login_form")
end
end
ユーザが存在しないときの処理
エラーメッセージを表示したりフォームに初期値を入れたりする。
バリデーションのエラーメッセージとは異なりfind_by
メソッドで検索したが存在しなかったとする。(自作で作る)変数@emailと@passwordを定義し、それぞれにparams[:email]
とparams[:password]
の値を代入し、フォームに入力した値が初期値となるようにする。(変数に代入した初期値を表示するためにフォームにvalue属性を追加する)
def login
if @user
...
else
@error_message="メールアドレスまたはパスワードが間違っています"
@email=params[:email]
@password=paras[:password]
render("users/login_form")
end
end
<% if @error_message %>
<div class="form_error">
<%= @error_message %>
</div>
<% end %>
<% form_tag("/login") do %>
<p>メールアドレス</p>
<input name="email" value="<%= @email %>">
<p>パスワード</p>
<input type="password" name="password" value="<%= @password %>">
<% end %>
ログイン処理
ログインページでユーザを特定した後、そのユーザの情報を保持し続ける必要がある。ページを移動してもユーザの情報を保持し続けるためにsession
という特殊な変数を扱う。session
に代入された値はブラウザに保存される。session
に値をsession[:キー名]=値
で代入した値がブラウザに代入される。
def login
@user=User.find_by(...)
#@userが存在する場合
if @user
session[:user_id]=@user.id
<li>
ログインしているユーザのid:
<%= session[:user_id] %>
</li>
ログアウト機能の作成
ログアウトする、つまりログイン状態でなくするにはsession[:user_id]
の値を空にする。session[:user_id]
にnil
を代入することで、session[:user_id]
を空にできる。
def logout
session[:user_id]=nil
flash[:notice]="ログアウトしました"
redirect_to("/login")
end
post "logout" => "users#logout"
session
の値を変更する場合にもgetではなくpostを使う。
ヘッダーメニューの表示内容を切り替える。(ログイン状態がログアウト状態かで表示する内容を変える)
<% if session[:user_id] %>
<li>
<%= session[:user_id] %>
</li>
<li>
<%= link_to("...","/about") %>
</li>
<% end %>
ユーザ登録時のログイン
ユーザ登録に成功したらそのままログイン状態となるようにする。そのためにユーザ登録時にパスワード用のフォームを追加する。また、ユーザ登録時にpaswordのカラムの値が設定されるようにする。
<p>パスワード</p>
<input name="password" type="password" value="<%= @user.password %>">
def create
@user=User.new(
name: params[:name],
email: params[:emai],
image_name: "default_user.jpg"
password: params[:password]
)
end
ユーザ登録が成功したときに作成したユーザがそのままログイン状態になるように、usersコントローラのcreateアクション内で作成したユーザのidをsession[:user_id]
に代入する。
if @user.save
session[:user_id]=@user.id
ユーザを表示する
session[:user_id]
の値をもとにログイン中のユーザ情報をデータベースから取得する。find_byメソッドを用いてusersテーブルからidカラムの値がsession[:user_id]
と等しいユーザを取得し、変数(current_user)とする。
<% current_user=User.find_by(id: session[:user_id]) %>
<li>
<%= link_to(current_user.name, "/users/#{current_user.id}") %>
</li>