学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

【学習5.0】【MacOSX】氏名認証

ユーザーモデルに氏名等の項目を追加します。


コマンド
rails g migration AddColumsToUser full_name


コマンド
rails db:migrate


Posticoでテーブル確認

full_nameフィールドの確認
full_nameフィールドの確認



ユーザモデルにバリデーションを追加します。


記述追加 app\models\user.rb(8行目)

validates :full_name, presence: true, length: {maximum: 50}



app\models\user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  #長さ50文字以下 入力必須
  validates :full_name, presence: true, length: {maximum: 50}

end



記述追加 application_controller.rb(4行目)

  #devise_controllerが読み込まれたら
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  #フィールドの更新を許可
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:full_name])
    devise_parameter_sanitizer.permit(:account_update, keys: [:full_name])
  end



app\controllers\application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  #devise_controllerが読み込まれたら
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  #フィールドの更新を許可
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:full_name])
    devise_parameter_sanitizer.permit(:account_update, keys: [:full_name])
  end
end



認証ビューを更新します。


更新 app\views\devise\registrations\new.html.erb

<section class="hero is-light is-fullheight">
  <div class="hero-body">
    <div class="container">
      <div class="columns is-centered">
        <div class="column is-6-table is-6-desktop is-6-widescreen">
          <div class="box">
            
            <div class="field has-text-centered">
              <strong>新規ユーザ登録</strong>
            </div>
            <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
              <%= render "devise/shared/error_messages", resource: resource %>
              <div class="field">
                <%= f.label :氏名, class: "label" %>
                <%= f.text_field :full_name, autofocus: true, autocomplete: "full_name", class: "input" %>
              </div>
              <div class="field">
                <%= f.label :メールアドレス, class: "label" %>
                <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "input" %>
              </div>
              <div class="field">
                <%= f.label :パスワード, class: "label" %>
                <% if @minimum_password_length %>
                <em>(<%= @minimum_password_length %> 文字以上)</em>
                <% end %><br />
                <%= f.password_field :password, autocomplete: "new-password", class: "input" %>
              </div>
              <div class="field">
                <%= f.label :確認, class: "label" %>
                <%= f.password_field :password_confirmation, autocomplete: "new-password", class: "input" %>
              </div>
              <div class="field">
                <%= f.submit "登録する", class: "button is-danger is-fullwidth m-t-10 m-b-10" %>
              </div>
            <% end %>
            <%= render "devise/shared/links" %>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>



ブラウザ確認
http://localhost:3000/users/sign_up


新規ユーザ登録
新規ユーザ登録


セッションビューの編集をします。


更新 app\views\devise\sessions\new.html.erb

<section class="hero is-light is-fullheight">
  <div class="hero-body">
    <div class="container">
      <div class="columns is-centered">
        <div class="column is-6-table is-6-desktop is-6-widescreen">
          <div class="box">
            
            <div class="field has-text-centered">
              <strong>ログイン</strong>
            </div>
            <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
              <div class="field">
                <%= f.label :メールアドレス, class: "label" %>
                <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "input" %>
              </div>
              <div class="field">
                <%= f.label :パスワード, class: "label" %>
                <%= f.password_field :password, autocomplete: "current-password", class: "input" %>
              </div>
              <% if devise_mapping.rememberable? %>
                <div class="field">
                  <%= f.check_box :remember_me %>
                  <%= f.label :ログインを保持する %>
                </div>
              <% end %>
              <div class="field">
                <%= f.submit "ログインする", class: "button is-danger is-fullwidth m-t-10 m-b-10" %>
              </div>
            <% end %>
            <%= render "devise/shared/links" %>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>



ブラウザ確認
http://localhost:3000/users/sign_in


ログイン
ログイン


アカウント編集ページを更新します。


更新 app\views\devise\registrations\edit.html.erb

<section class="hero is-light is-fullheight">
  <div class="hero-body">
    <div class="container">
      <div class="columns is-centered">
        <div class="column is-6-table is-6-desktop is-6-widescreen">
          <div class="box">
            
            <div class="field has-text-centered">
              <strong>ユーザ登録情報編集</strong>
            </div>
            <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
              <%= render "devise/shared/error_messages", resource: resource %>
              <div class="field">
                <%= f.label :氏名, class: "label" %>
                <%= f.text_field :full_name, autofocus: true, autocomplete: "full_name", class: "input" %>
              </div>
              <div class="field">
                <%= f.label :メールアドレス, class: "label" %>
                <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "input" %>
              </div>
              <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
                <div>現在、確認を待っています: <%= resource.unconfirmed_email %></div>
              <% end %>
              <div class="field">
                <%= f.label :パスワード, class: "label"  %> <i>(変更しない場合は空白のままにします)</i>
                <%= f.password_field :password, autocomplete: "new-password", class: "input" %>
                <% if @minimum_password_length %>
                  <br />
                  <em><%= @minimum_password_length %> 文字以上</em>
                <% end %>
              </div>
              <div class="field">
                <%= f.label :確認, class: "label"  %>
                <%= f.password_field :password_confirmation, autocomplete: "new-password", class: "input" %>
              </div>
              <div class="field">
                <%= f.label :現在のパスワード, class: "label"  %> <i>(変更するには現在のパスワードが必要です)</i><br />
                <%= f.password_field :current_password, autocomplete: "current-password", class: "input" %>
              </div>
              <div class="field">
                <%= f.submit "更新する", class: "button is-danger is-fullwidth" %>
              </div>
            <% end %>
            <%= link_to "戻る", :back, class: "button is-fullwidth m-t-10" %>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>



ブラウザ確認
ログインしておく必要があります。
http://localhost:3000/users/edit


氏名カラムが更新できる
氏名カラムが更新できる


スタイルを更新します。


app\assets\stylesheets\application.scss
これからのものもすべて書いておきます。
21行目からの記述を追加しています。

/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
 * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self
 */
 
 @import 'bulma';
 @import 'bulma-extensions';
 

 $spaceamounts: (0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100);
 $sides: (top, bottom, left, right);
 @each $space in $spaceamounts {
   @each $side in $sides {
     .m-#{str-slice($side, 0, 1)}-#{$space} {
       margin-#{$side}: #{$space}px !important;
     }
     .p-#{str-slice($side, 0, 1)}-#{$space} {
       padding-#{$side}: #{$space}px !important;
     }
   }
   .m-#{$space} {
     margin: #{$space}px !important;
   }
   .p-#{$space} {
     padding: #{$space}px !important;
   }
   .h-#{$space} {
     margin-top: #{$space}px !important;
     margin-bottom: #{$space}px !important;
   }
   .f-#{$space} {
     font-size: #{$space}px !important;
   }
 }
 .is-horizontal-center {
   justify-content: center;
 }
 .small-title {
   font-size: 10px;
 }


 //ホームページ用
 .has-bg-img {
   background: url('/assets/home/background01.jpg') center center;
   background-size: cover;
 }

 //ナビバーのアバター画像位置
 .image {
   //margin-top: 0.6rem;
   display: flex; /* flexに */
   align-items: center;
 }

 
 // googlフォント用
 .title {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .button {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .field {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .all {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .navbar-item {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .input {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .card-content {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .section {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .card-header-title is-centered {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 .modal-card-title {
   font-family: 'Kosugi Maru', "Helvetica Neue", "Helvetica", "Arial", sans-serif;
 }
 



レンダーファイルを更新します。


記述更新 app\views\devise\shared\_links.html.erb

<br/>
<div class="all">
<%- if controller_name != 'sessions' %>
  ユーザ登録がお済みの方は<%= link_to "ログイン", new_session_path(resource_name) %>してください。<br />
  <br/>
  <p>登録ボタンを押すとメールが送信されます。</p>
  <p>メールに記載されているリンクをクリックするとアカウントが有効化されます。</p>
<% end %>

<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
  <%= link_to "新規ユーザ登録", new_registration_path(resource_name) %>がお済みでない方は先に登録をお願い致します。<br />
<% end %>

<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
  <%= link_to "パスワードをお忘れですか?", new_password_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
<br/>
  <%= link_to "確認のメールが届かない方はこちら", new_confirmation_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
  <%= link_to "ロック解除の手順を受け取っていませんか?", new_unlock_path(resource_name) %><br />
<% end %>


</div>



パスワードリセットのビューを更新します。


記述更新 app\views\devise\passwords\new.html.erb

<section class="hero is-light is-fullheight">
  <div class="hero-body">
    <div class="container">
      <div class="columns is-centered">
        <div class="column is-6-table is-6-desktop is-6-widescreen">
          <div class="box">

            <div class="field has-text-centered">
              <strong>パスワードをお忘れですか?</strong>
            </div>
            <br/>


            <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
              <%= render "devise/shared/error_messages", resource: resource %>

              <div class="field">
                <%= f.label :メールアドレス, class: "label" %>
                <%= f.email_field :email, autofocus: true, autocomplete: "email", placeholder: "メールアドレスを入力してください", class: "input" %>
              </div>
              <br/>
              <div class="actions">
                <%= f.submit "パスワード再設定メールを送る", class: "button is-danger is-fullwidth m-t-10 m-b-10" %>
              </div>
            <% end %>
            <br/>
            <p>メールに記載されているリンクをクリックするとパスワードの再設定ができます。</p>

          </div>
        </div>
      </div>
    </div>
  </div>
</section>



ブラウザ確認
http://localhost:3000/users/password/new


パスワードをお忘れの方用
パスワードをお忘れの方用


パスワード変更のビューを更新します。
メール送信設定を行なった後でなければ確認できませんが変更しておきます。


app\views\devise\passwords\edit.html.erb

<section class="hero is-light is-fullheight">
  <div class="hero-body">
    <div class="container">
      <div class="columns is-centered">
        <div class="column is-6-table is-6-desktop is-6-widescreen">
          <div class="box">

            <div class="field has-text-centered">
              <strong>パスワードを変更します</strong>
            </div>
            <br/>


            <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
              <%= render "devise/shared/error_messages", resource: resource %>
              <%= f.hidden_field :reset_password_token %>

              <div class="field">

                <% if @minimum_password_length %>
                  <em>新しいパスワード(<%= @minimum_password_length %> 文字以上)</em><br />
                <% end %>
                <%= f.password_field :password, autofocus: true, autocomplete: "new-password", placeholder: "新しいパスワードを入力して下さい", class: "input" %>
              </div>
              <br/>
              <div class="field">
                <%= f.password_field :password_confirmation, autocomplete: "new-password", placeholder: "確認", class: "input" %>
              </div>
              <br/>
              <div class="actions">
                <%= f.submit "パスワードを変更する", class: "button is-danger is-fullwidth m-t-10 m-b-10" %>
              </div>
            <% end %>


          </div>
        </div>
      </div>
    </div>
  </div>
</section>



ナビゲーションバーのドロップダウンの部分を氏名表示に変更します。
確認するには氏名のカラムを更新しておく必要があります。


1.30行目を以下の記述に変更しています。

<a class="navbar-item"><%= current_user.full_name %></a>



2.32行目に以下のリンクを追加しています。

<%= link_to  "ユーザ登録情報編集", edit_user_registration_path, class: "navbar-item" %>



記述更新 app\views\shared\_navbar.html.erb

<nav class="navbar is-link" role="navigation" aria-label="main navigation">
    <div class="navbar-brand">
        <a class="navbar-item" href="/">
            <h1>テストサイトGakushuu</h1>
        </a>
        <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
        </a>
    </div>

    <div id="navbarBasicExample" class="navbar-menu">
        <div class="navbar-end">
            <a class="navbar-item"></a>
            <a class="navbar-item"></a>

            <!-- もしログインしていなかったら-->
            <% if (!user_signed_in?) %>
                <div class="navbar-item">
                    <div class="buttons">
                        <%= link_to  "新規ユーザ登録", new_user_registration_path, class: "button is-info" %>
                        <%= link_to  "ログイン", new_user_session_path, class: "button is-light" %>
                    </div>
                </div>

            <!-- ログインしていたら -->
            <% else %>
                <div class="navbar-item has-dropdown is-hoverable" style="margin-right: 100px;">
                    <a class="navbar-item"><%= current_user.full_name %></a>
                    <div class="navbar-dropdown">
                        <%= link_to  "ユーザ登録情報編集", edit_user_registration_path, class: "navbar-item" %>
                        <a href="" class="navbar-item"></a>
                        <hr class="navbar-divider">
                        <%= link_to  "ログアウト", destroy_user_session_path, method: :delete, class: "navbar-item" %>
                    </div>
                </div>
            <% end %>
        </div>
    </div>
</nav>

<script>
    $(document).ready(function() {
        // navbar burgerアイコンでクリックイベントを確認する
        $(".navbar-burger").click(function() {
            // 「navbar-burger」と「navbar-menu」の両方で「is-active」クラスを切り替えます
            $(".navbar-burger").toggleClass("is-active");
            $(".navbar-menu").toggleClass("is-active");
        });
    });
</script>



ブラウザ確認
http://localhost:3000/

氏名表示
氏名表示