LoginSignup
1
2

More than 1 year has passed since last update.

[Rails] deviseで2種類のユーザーアカウントを作成する①

Posted at

はじめに

ユーザー管理機能が存在するアプリケーションを作成する際に、2種類のユーザーを作りたい時ないですか?

例えば、管理者ユーザーと一般ユーザーの2種類に分けて、管理者ユーザーにだけ、ある特別な操作を可能にしてあげたりって感じです。

私は教育現場で使えるようなアプリケーションを作成しようと思って、生徒のユーザと先生のユーザーの2種類作りたいと考えまして、いろいろ調べたりして、一応できたので、まとめておきたいと思います。

もっと簡単な方法があるぞ!とか、間違ってるぞ、おい!って内容があればお知らせいただければ幸いです。

rootのコントローラーとビュー

まずはコントローラー

ターミナル
% rails g controller home index

ルーティングを見ます

config/routes.rb(変更前)
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

これを↓に書き換えてください

config/routes.rb(変更後)
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のインストール

おなじみの

Gemfile
# 一番下の行に記述
gem 'devise'
gem 'devise-i18n' # ←もしdeviseの日本語化が必要であれば

からの

ターミナル
% bundle install

% rails g devise:install

次がいつもと違うところです。
deviseの設定を変更しましょう。

config/initializers/devise.rbを開てください。
恐ろしい行のコードがコメントアウトされています。

その中から

config/initializers/devise.rb(変更前)
#config.scoped_views = false
# 中略
#config.sign_out_all_scopes = true

この二つのコメントアウトを探し出して、コメントアウトを外し、下記のように変更してください。
command + F を使うとすぐ見つけられます。(Mac)
※trueとfalseを変更していることに注目してください

config/initializers/devise.rb(変更後)
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のモデルを下記のように変更をします。

app/models/teacher.rb (変更前)
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 という記述をコメントアウトします。

app/models/teacher.rb(変更後)
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のコントローラーがぶつかってしまっています(同じコントローラーを使っている)

解消するためにルーティングを下記のように変更しましょう

config/routes.rb(変更後)
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種類のユーザーを使い分けて開発を進めていくのかがわからないと思いますので次回、それをテーマに記事を投稿したいと思います。

1
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
1
2