はじめに
ユーザー管理機能が存在するアプリケーションを作成する際に、2種類のユーザーを作りたい時ないですか?
例えば、管理者ユーザーと一般ユーザーの2種類に分けて、管理者ユーザーにだけ、ある特別な操作を可能にしてあげたりって感じです。
私は教育現場で使えるようなアプリケーションを作成しようと思って、生徒のユーザと先生のユーザーの2種類作りたいと考えまして、いろいろ調べたりして、一応できたので、まとめておきたいと思います。
もっと簡単な方法があるぞ!とか、間違ってるぞ、おい!って内容があればお知らせいただければ幸いです。
rootのコントローラーとビュー
まずはコントローラー
% rails g controller home index
ルーティングを見ます
Rails.application.routes.draw do
get 'home/index'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
これを↓に書き換えてください
Rails.application.routes.draw do
root to: 'home#index'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
'home/index' が 'home#index'になっていることにも注意してくださいね!
deviseのインストール
おなじみの
# 一番下の行に記述
gem 'devise'
gem 'devise-i18n' # ←もしdeviseの日本語化が必要であれば
からの
% bundle install
% rails g devise:install
次がいつもと違うところです。
deviseの設定を変更しましょう。
config/initializers/devise.rbを開てください。
恐ろしい行のコードがコメントアウトされています。
その中から
#config.scoped_views = false
# 中略
#config.sign_out_all_scopes = true
この二つのコメントアウトを探し出して、コメントアウトを外し、下記のように変更してください。
command + F を使うとすぐ見つけられます。(Mac)
※trueとfalseを変更していることに注目してください
config.scoped_views = true
# 中略
config.sign_out_all_scopes = false
config.scoped_views = true は複数のモデルで個別のログイン画面を使うための記述です。
config.sign_out_all_scopes = false は一つののモデルでログアウトしたときに、もう片方も一緒にログアウトしてしまうことを防ぎます。
##deviseのモデル作成
普通にモデルを二つdeviseで作ってOKです。マイグレーションまで一気にやっちゃいましょう!
ここでは私の開発中のアプリケーションに因んでteacherモデルとstudentモデルとします。
% rails g devise teacher
% rails g devise student
% rails db:migrate
もし、勝手に新規登録されたくないユーザーがある場合はそのユーザーのモデルの記述を書き換えます。
例えば、私の場合は先生ユーザーのアカウントを勝手にホイホイ作られると困るので、teacherのモデルを下記のように変更をします。
class Teacher < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
これの**:registerable** という記述をコメントアウトします。
class Teacher < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, #:registerable,
:recoverable, :rememberable, :validatable
end
よーし、これで完了!パスがしっかり割り振られているか確認しましょう!
% rails routes
下記のような結果が。。。
Prefix Verb URI Pattern Controller#Action
new_student_session GET /students/sign_in(.:format) devise/sessions#new
student_session POST /students/sign_in(.:format) devise/sessions#create
destroy_student_session DELETE /students/sign_out(.:format) devise/sessions#destroy
new_student_password GET /students/password/new(.:format) devise/passwords#new
edit_student_password GET /students/password/edit(.:format) devise/passwords#edit
student_password PATCH /students/password(.:format) devise/passwords#update
PUT /students/password(.:format) devise/passwords#update
POST /students/password(.:format) devise/passwords#create
cancel_student_registration GET /students/cancel(.:format) devise/registrations#cancel
new_student_registration GET /students/sign_up(.:format) devise/registrations#new
edit_student_registration GET /students/edit(.:format) devise/registrations#edit
student_registration PATCH /students(.:format) devise/registrations#update
PUT /students(.:format) devise/registrations#update
DELETE /students(.:format) devise/registrations#destroy
POST /students(.:format) devise/registrations#create
new_teacher_session GET /teachers/sign_in(.:format) devise/sessions#new
teacher_session POST /teachers/sign_in(.:format) devise/sessions#create
destroy_teacher_session DELETE /teachers/sign_out(.:format) devise/sessions#destroy
new_teacher_password GET /teachers/password/new(.:format) devise/passwords#new
edit_teacher_password GET /teachers/password/edit(.:format) devise/passwords#edit
teacher_password PATCH /teachers/password(.:format) devise/passwords#update
PUT /teachers/password(.:format) devise/passwords#update
POST /teachers/password(.:format) devise/passwords#create
cancel_teacher_registration GET /teachers/cancel(.:format) devise/registrations#cancel
new_teacher_registration GET /teachers/sign_up(.:format) devise/registrations#new
edit_teacher_registration GET /teachers/edit(.:format) devise/registrations#edit
teacher_registration PATCH /teachers(.:format) devise/registrations#update
PUT /teachers(.:format) devise/registrations#update
DELETE /teachers(.:format) devise/registrations#destroy
POST /teachers(.:format) devise/registrations#create
root GET / home#index
これ、おかしいのわかるでしょうか。
右端のController#Actionに注目してください。
teacherとstudentのコントローラーがぶつかってしまっています(同じコントローラーを使っている)
解消するためにルーティングを下記のように変更しましょう
Rails.application.routes.draw do
devise_for :students, controllers: {
sessions: 'students/sessions',
passwords: 'students/passwords',
registrations: 'students/registrations'
}
devise_for :teachers, controller: {
sessions: 'teachers/sessions',
passwords: 'teachers/passwords',
registrations: 'teachers/registrations'
}
root to: 'home#index'
end
これでもう一度
% rails routes で確認します。
Prefix Verb URI Pattern Controller#Action
new_student_session GET /students/sign_in(.:format) students/sessions#new
student_session POST /students/sign_in(.:format) students/sessions#create
destroy_student_session DELETE /students/sign_out(.:format) students/sessions#destroy
new_student_password GET /students/password/new(.:format) students/passwords#new
edit_student_password GET /students/password/edit(.:format) students/passwords#edit
student_password PATCH /students/password(.:format) students/passwords#update
PUT /students/password(.:format) students/passwords#update
POST /students/password(.:format) students/passwords#create
cancel_student_registration GET /students/cancel(.:format) students/registrations#cancel
new_student_registration GET /students/sign_up(.:format) students/registrations#new
edit_student_registration GET /students/edit(.:format) students/registrations#edit
student_registration PATCH /students(.:format) students/registrations#update
PUT /students(.:format) students/registrations#update
DELETE /students(.:format) students/registrations#destroy
POST /students(.:format) students/registrations#create
new_teacher_session GET /teachers/sign_in(.:format) teachers/sessions#new
teacher_session POST /teachers/sign_in(.:format) teachers/sessions#create
destroy_teacher_session DELETE /teachers/sign_out(.:format) teachers/sessions#destroy
new_teacher_password GET /teachers/password/new(.:format) teachers/passwords#new
edit_teacher_password GET /teachers/password/edit(.:format) teachers/passwords#edit
teacher_password PATCH /teachers/password(.:format) teachers/passwords#update
PUT /teachers/password(.:format) teachers/passwords#update
POST /teachers/password(.:format) teachers/passwords#create
cancel_teacher_registration GET /teachers/cancel(.:format) teachers/registrations#cancel
new_teacher_registration GET /teachers/sign_up(.:format) teachers/registrations#new
edit_teacher_registration GET /teachers/edit(.:format) teachers/registrations#edit
teacher_registration PATCH /teachers(.:format) teachers/registrations#update
PUT /teachers(.:format) teachers/registrations#update
DELETE /teachers(.:format) teachers/registrations#destroy
POST /teachers(.:format) teachers/registrations#create
root GET / home#index
これでteacherかstudentのどちらかの配下になったかと思います。
deviseのビューとコントローラー作成
% rails g devise:views teachers
% rails g devise:views students
% rails g devise:controllers teachers
% rails g devise:controllers students
ちゃんとビューとコントローラーが働いているかは、rails s でサーバーを立ち上げてから
直接、localhost:3000/students/sign_in,
localhost:3000/teachers/sign_inを打ち込んで確かめましょう。
deviseの質素なログイン画面が見れるはずです。
teachersの方はルーティングで:registerable という記述をコメントアウトしたため、Sign upのリンクがありません。
ひとまずこれで2種類のユーザーの作成は完了です。
最後に
一応、これで2種類のユーザーは作成できましたが、このあと、どのように2種類のユーザーを使い分けて開発を進めていくのかがわからないと思いますので次回、それをテーマに記事を投稿したいと思います。