🦓

[Rails]パスワードの更新 3/20

2023/06/17に公開

はじめに

新規登録・ログイン機能の次に、パスワードの更新機能も作っていきます。

新規登録・ログインについて

環境

ruby: 3.0.0
rails: 6.1.7

流れ

  1. routes.rbを編集する
  2. Passwordsコントローラーを作成する
  3. application_controller.rbを編集する
  4. _header.html.erbを編集する
  5. ビューを作成する

routes.rbを編集する

パスワードの更新用ルートを追加します。

config/routes.rb
Rails.application.routes.draw do
...
  get "password", to: "passwords#edit"
  patch "password", to: "passwords#update"
end

Passwordsコントローラーを作成する

$ bin/rails g controller Passwords
Running via Spring preloader in process 82464
      create  app/controllers/passwords_controller.rb
      invoke  erb
      create    app/views/passwords

パスワードを更新しましたらユーザをログアウトし、もう一度ログインさせます。

app/controllers/passwords_controller.rb
class PasswordsController < ApplicationController
    before_action :user_login_required

    def edit

    end

    def update
        if Current.user.update(password_params)
            flash[:success] = "パスワールドを更新されました。もう一度ログインお願いします。"
            session[:user_id] = nil
            redirect_to login_path
        else
            flash[:danger] = "パスワードの更新が失敗しました。もう一度試してください。"
            render :edit, status: :unprocessable_entity
        end


    end

    private

    def password_params
        params.require(:user).permit(:password, :password_confirmation)
    end
end

status: :unprocessable_entity

status: :unprocessable_entityは、HTTPのレスポンスステータスコードを422(Unprocessable Entity)に設定するオプションです。これは、リクエストがバリデーションエラーやクライアント側の問題などの理由で処理できない場合を示します。

render :edit, status: :unprocessable_entityを使用することで、フォームの送信が失敗したりバリデーションエラーが発生した場合に、エラーメッセージやバリデーションエラーを含んだ編集用のビューテンプレートをユーザーに表示することができます。これにより、ユーザーはエラーを修正してフォームを再送信することができます。

例:

application_controller.rbを編集する

ユーザがログインした状態でないとパスワードを更新できないようにbefore_actionを使ってまずログインさせます。
他のコントローラーとアクションにも使われるため、application_controllerb.rbにまとめていきます。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
...
    def user_login_required
        unless Current.user
            flash[:warning] = "まだログインしてないです。"
            redirect_to login_path
        end
    end
end

_header.html.erbを編集する

パスワードを編集できるようにリンクを追加します。

app/views/shared/_header.html.erb
<ul class="navbar-nav ms-auto">
  <% if Current.user %>
    <li class="nav-item dropdown ms-auto">
       <%= link_to Current.user.user_name, password_path, class: "nav-link dropdown-toggle", id: "navbarScrollingDropdown", role: "button", data: { bs_toggle: "dropdown" }, aria: { expanded: "false" } %>
       <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarScrollingDropdown">
          <li class="nav-item">
                <%= link_to "編集", password_path, class: 'nav-link' %>
          </li>
          <li class="nav-item">
                <%= link_to "ログアウト", logout_path, method: :delete, class: 'nav-link' %>
          </li>
   <% else %>
          <li class="nav-item">
                <%= link_to "ログイン", login_path, class: 'nav-link' %></li>
          <li class="nav-item">
                <%= link_to "新規登録", signup_path, class: 'nav-link' %></li>
          </ul>
   <% end %>
     </li>
</ul>

Image from Gyazo

ビューを作成する

passwords/edit.html.erbを作成します。

app/views/passwords/edit.html.erb
<h1>Edit Password</h1>
<%= form_with model: Current.user, url: password_path do |form| %>
  <% if Current.user.errors.any? %>
    <div class="alert alert-danger">
      <% Current.user.errors.full_messages.each do |message|  %>
        <div>
          <%= message %>
        </div>
      <% end  %>
    </div>
  <% end %>
  <div class="form-group">
    <%= form.label :password %>
    <%= form.password_field :password, placeholder: "Enter your new password", class: "form-control mb-3"  %>
  </div>
  <div class="form-group">
    <%= form.label :password_confirmation %>
    <%= form.password_field :password_confirmation, placeholder: "Enter your password again", class: "form-control mb-3"  %>
  </div>
  <%= form.submit "Update password", class:'btn btn-primary' %>
<% end %>

終わりに

これよりパスワードの更新機能を追加しました。

Discussion