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?
を記述する