2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

1 Railsでエンドユーザーのサインアップとログイン機能、管理者のログイン機能を実装

Last updated at Posted at 2022-11-09

1 Deviseの導入

(1)Gemfileに以下を追記する

gem 'devise'

(2) bundle intallを実行する

2 顧客 , 管理者用のモデルを作成する

顧客のモデルを作成する

rails g model devise Enduser

管理者用のモデルを作成する

rails g model Admin

3 顧客 , 管理者用のテーブルを作成する

それぞれのマイグレーションファイルに以下を追記する

devise_create_end_users.rb

      t.string :first_name  名前 姓
      t.string :katakana_first_name 名前  カナ 姓
      t.string :last_name  名前 
      t.string :katakana_last_name  名前 カナ 
      t.string :postal_code  郵便番号
      t.string :address  住所
      t.string :telephone_number  電話番号
Adminは特に、追記することなし

devise_create_admins

class DeviseCreateAdmins < ActiveRecord::Migration[5.2]
  def change
    create_table :admins do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      # t.integer  :sign_in_count, default: 0, null: false
      # t.datetime :current_sign_in_at
      # t.datetime :last_sign_in_at
      # t.string   :current_sign_in_ip
      # t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      t.timestamps null: false
    end

    add_index :admins, :email,                unique: true
    add_index :admins, :reset_password_token, unique: true
    # add_index :admins, :confirmation_token,   unique: true
    # add_index :admins, :unlock_token,         unique: true
  end
end

migrationファイルをデータベースに反映させる

rails db:migrate

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

devise用のコントローラを作成する

1 使用する機能のみをルーティングを行える
2 ログイン前に特定のメソッドを実行することができるbefore_actionなどを使用できる
3 デフォルトのDeviseの設定のみでは実現することができない機能を追加できるようになる

顧客用のdeviseのコントローラを作成する

 rails g devise:controllers customer

管理者用のdeviseのコントローラを作成する

rails g devise:controllers admin

5 viewを作成する

rails g devise:views publics
rails g devise:views admins

この時viewフォルダが作成されるが名前を下記の通りに変更する

publics -> public

admins -> admin

フォルダの名前を変更したので

<%= render ~

の記述を変更する必要がある!!

管理者側のViewの編集
<%= render "admin/shared/links" %>
顧客側のview編集
<%= render "customer/shared/links" %>
customer/registrations/new.html.erb
<%= render "customer/shared/error_messages", resource: resource %>

6 ルーティングの編集

devise_for :customers
devise_for :admins
これらで作られたルーティングでは、、、

1 先程作成したコントローラーの記述を変更してもその処理を行うことができない。
2 URLに関してもアプリケーション詳細設計の通りに実装を行うことができない

=> このルーティングを消して新たなルーティングを↓のように作り直す。

(1)ルーティングを作り直す

顧客のコントローラに関するルーティング
devise_for :end_users, controllers: {
  registrations: "public/registrations",
  sessions: 'public/sessions'
}
管理者のコントローラに関するルーティング
devise_for :admin, controllers:{
    sessions: "admin/sessions"
  }
ポイント
このように記述することで
publicフォルダとadminフォルダでsessions_controller.rbが2つあるので
どちらのsessions_controller.rbを参照するのか指定出来る。

(2)不要なルーティングを削除する

skipオプションを使ってルーティングを削除する

顧客側のルーティング

 devise_for :end_users , path: 'public',  skip: [:passwords,],controllers: {
    registrations: "public/registrations",
    sessions: 'public/sessions'
  }

管理者側のルーティング

devise_for :admin, skip: [:registrations, :passwords] ,controllers: {
  sessions: "admin/sessions"
}
ポイント

1 skipというオプションを使うことで指定したコントローラのルーティングを削除する

2 デフォルトのURLの先頭を変える方法
RailsのdeviseのController,View,URLのカスタマイズ(初心者向け)より、
end_users/~をpublic/~にする方法

path: 'public'

を追記する

(3) 削除したルーティングへのリンクを削除する

app/views/public/shared/_links.html.erb

<%- if controller_name != 'sessions' %>
  <%= link_to "Log in", new_session_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
  <%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end %>

--------------------------------ここから削除--------------------------------
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
  <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
  <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
  <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %>
    <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
  <% end %>
<% end %>
--------------------------------ここまで削除--------------------------------

app/views/admin/shared/_links.html.erb

<%- if controller_name != 'sessions' %>
  <%= link_to "Log in", new_session_path(resource_name) %><br />
<% end %>

--------------------------------ここから削除--------------------------------
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
  <%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
  <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
  <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
  <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %>
    <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
  <% end %>
<% end %>
--------------------------------ここまで削除--------------------------------

7 エンドユーザーのサインアップにフォームを作成する

<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "public/shared/error_messages", resource: resource %>

  <div class="field">
    <%= f.label :first_name %><br />
    <%= f.text_field :first_name ,autofocus: true%>
  </div>

  <div class="field">
    <%= f.label :katakana_first_name %><br />
    <%= f.text_field :katakana_first_name %>
  </div>

  <div class="field">
    <%= f.label :last_name %><br />
    <%= f.text_field :last_name%>
  </div>

  <div class="field">
    <%= f.label :katakana_last_name%><br />
    <%= f.text_field :katakana_last_name%>
  </div>



  <div class="field">
    <%= f.label :email %><br />
     <%= f.email_field :email,  autocomplete: "email" %>
  </div>

  <div class="field">
    <%= f.label :address %><br />
    <%= f.text_area :address %>
  </div>

  <div class="field">
    <%= f.label :postal_code %><br />
    <%= f.text_field :postal_code %>
  </div>

  <div class="field">
    <%= f.label :telephone_number %><br />
    <%= f.text_field :telephone_number %>
  </div>

  <div class="field">
    <%= f.label :password %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "new-password" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
  </div>

  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

<%= render "public/shared/links" %>

8 エンドユーザー , 管理者のトップページを作成する

(1)コントローラーを作成する

管理者のtopページのコントローラを作成する

rails g controller admin/homes

エンドユーザーのtopページのコントローラを作成する

rails g controller public/homes
(2)アクションを追加する

管理者

class Admin::HomesController < ApplicationController
  def top
  end
end

エンドユーザー

class Public::HomesController < ApplicationController
  def top
  end
end
(3) viewを作成する

管理者
app/views/admin/homes/top.html.erb

<h1>管理者トップページ</h1>

app/views/public/homes/top.html.erb

<h1>エンドユーザ#トップページ</h1>
(4) ルーティングを作成する

管理者用

    namespace :admin do
        get '/' => 'homes#top'
    end

エンドユーザ用

root to: 'public/homes#top'

9 エンドユーザーのマイページを作成する

(1) コントローラーを作成する
rails g controller public/customers
(2) アクションを定義する
def show
    @customer = current_end_user
end
(3) ビューを作成する

public/customers/show.html.erb

<h1>エンドユーザ#マイページ</h1>
(4) ルーティングを作成する
get 'customers/mypage' => 'public/customers#show'

10 ログアウトetc...の遷移先を設定する

エンドユーザーの新規登録時の遷移を設定する
app/controllers/public/registrations_controller.rb

サインアップした遷移先
def after_sign_up_path_for(resource)
    customers_mypage_path
end

app/controllers/public/sessions_controller.rb

ログインした遷移先
def after_sign_in_path_for(resource)
   root_path
end

ログアウトした遷移先
def after_sign_out_path_for(resource)
   root_path
end

11 seedでadminにログインできるようにする

seedとは、、、
seedファイルにデータベースへのデータ投入の処理を追記していき、
railsコマンドを実行することでデータベースに初期データとしてデータが投入される

(1) seedファイルに初期データを記述する
Admin.create!(email: '123@456', password: '123456')

モデル名.create(カラム名: 入れるデータ)で作成する

(2)コマンドを実行する
$rails db:seed

エラー発生: seedできてなかった!?

seeds.rb

Admin.create(email: '123@456',encrypted_password: '123456')

開発段階では、passwordのカラムはpassword
保存される時にencrypted_passwordというカラムになる

解決法

seeds.rbの中身をこちらに変更し、コマンドを実行する

Admin.create!(email: '123@456', password: '123456')

!をつけるとcreate,update出来ない時、エラーを出力する
(railsのエラーが原因で失敗した際、本来はrollbackと表示されるだけで原因がわからない。
!をつけることで分かるようになる)

エラー発生: エンドユーザーの新規登録ができない!?

class Public::RegistrationsController < Devise::RegistrationsController

  def after_sign_up_path_for(resource)
    customers_mypage_path
  end

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name,:katakana_first_name,:last_name,:katakana_last_name,:postal_code,:address,:telephone_number,:telephone_number])
  end

end

新規登録時のターミナル

Unpermitted parameters: :first_name, :katakana_first_name, :last_name, :katakana_last_name, :address, :postal_code, :telephone_number
   (0.1ms)  begin transaction
   /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.6/lib/active_record/log_subscriber.rb:98
  EndUser Exists (0.2ms)  SELECT  1 AS one FROM "end_users" WHERE "end_users"."email" = ? LIMIT ?  [["email", "2@2"], ["LIMIT", 1]]
   /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.6/lib/active_record/log_subscriber.rb:98
   (0.0ms)  rollback transaction

原因:

def configure_permitted_parameters
   devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name,:katakana_first_name,:last_name,:katakana_last_name,:postal_code,:address,:telephone_number,:telephone_number])
end

この記述は、記述しただけでは使ってない。
before_action :configure_permitted_parameters, if: :devise_controller?と記述することで初めて使う

解決策:

before_action :configure_permitted_parameters, if: :devise_controller?

を記述する

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?