2
2

More than 3 years have passed since last update.

ログイン機能の作成(Ruby on Rails)

Posted at

プログラミングの勉強日記

2020年7月18日 Progate Lv.211
Ruby on RailsⅧ

ログインページの作成

 ログインするためにはログインページからメールアドレスやパスワードなどの情報をRaisに送信する。送信された情報をもとに操作しているユーザを特定しログイン状態とする。ログインページを作るためにルーティング、アクション、ビューを追加する。

routes.rb
get "login" => "users#login_form"
users_controller.rb
def login_form
end

<input>タグのtype属性をpasswordとすると入力した文字が伏字となるパスワード用のフォームになる。

login_form.html.erb
<p>パスワード</p>
<input type="password">

パスワードカラムの追加

 rails generate migrationを用いてadd_password_to_usersというファイル名のマイグレーションファイルを作成する。

ターミナル
$ rails generate add_password_to_users
マイグレーションを変更後
$ rails db:migrate
..._add_password_to_users/rb
class AddPasswordToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :password, :string
  end
end

ユーザの情報には必ずパスワードが存在してほしいので、バリデーションをかける。

models/user.rb
class User < ApplicationRecord
  validates :password, {presence: true}
end

ユーザの特定

 フォームに入力されたメールアドレスとパスワードは、params[:email]params[:password]で受け取れる。usersテーブルから入力された値に一致するユーザを取得し、変数@userに代入する。フォームから送信されたメールアドレスとパスワードに一致するユーザが存在する場合はフラッシュメッセージを表示し、投稿一覧ページにリダイレクトする。ユーザが存在しない場合はログインページを再表示する。

users_controller.rb
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属性を追加する)

users_controller.rb
def login
  if @user 
    ...
  else
    @error_message="メールアドレスまたはパスワードが間違っています"
    @email=params[:email]
    @password=paras[:password]
    render("users/login_form")
  end
end
login_form.html.erb
<% 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[:キー名]=値で代入した値がブラウザに代入される。

users_controller.rb
def login
  @user=User.find_by(...)
  #@userが存在する場合
  if @user
    session[:user_id]=@user.id
application.html.erb
<li>
  ログインしているユーザのid:
  <%= session[:user_id] %>
</li>

ログアウト機能の作成

 ログアウトする、つまりログイン状態でなくするにはsession[:user_id]の値を空にする。session[:user_id]nilを代入することで、session[:user_id]を空にできる。

users_controller.rb
def logout
  session[:user_id]=nil
  flash[:notice]="ログアウトしました"
  redirect_to("/login")
end
routes.rb
post "logout" => "users#logout"

 sessionの値を変更する場合にもgetではなくpostを使う。

ヘッダーメニューの表示内容を切り替える。(ログイン状態がログアウト状態かで表示する内容を変える)

application.html.erb
<% if session[:user_id] %>
  <li>
    <%= session[:user_id] %>
  </li>
  <li>
    <%= link_to("...","/about") %>
  </li>
<% end %>

ユーザ登録時のログイン

 ユーザ登録に成功したらそのままログイン状態となるようにする。そのためにユーザ登録時にパスワード用のフォームを追加する。また、ユーザ登録時にpaswordのカラムの値が設定されるようにする。

new.html.erb
<p>パスワード</p>
<input name="password" type="password" value="<%= @user.password %>">
user_controller.rb
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]に代入する。

user_controller.rb
if @user.save
  session[:user_id]=@user.id

ユーザを表示する

 session[:user_id]の値をもとにログイン中のユーザ情報をデータベースから取得する。find_byメソッドを用いてusersテーブルからidカラムの値がsession[:user_id]と等しいユーザを取得し、変数(current_user)とする。

layouts/application.html.erb
<% current_user=User.find_by(id: session[:user_id]) %>
<li>
  <%= link_to(current_user.name, "/users/#{current_user.id}") %>
</li>
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2