複数権限でのdeviseの実装(管理者機能の作成)
管理者機能の作成
今回は、Gemのdeviseを使用して複数権限の管理者権限の作成を実施していく。(Member(会員)とAdmin(管理者))
前提条件
作業環境
エディエタ:AWS
ブラウザ:Google Chrome
Ruby : 3.1.2
Rails : 6.1.7.4
deviseはインストール済み
作業は下記を参照(deviseのインストールまで)
作業手順
モデルの作成
コントローラの作成
ビューの作成
ルーティングの記述
不要な記述の削除
モデルの作成
会員用の情報・管理者用の情報を保存するための会員・管理者テーブルを作成するために下記のコマンドを実行。
$ rails g devise Member #会員モデルの作成 $ rails g devise Admin #管理者モデルの作成
上記を実行すると下記のようにファイルが作成される。
$ rails g devise Member Running via Spring preloader in process 12143 invoke active_record create db/migrate/20230905012027_devise_create_members.rb create app/models/member.rb invoke test_unit create test/models/member_test.rb create test/fixtures/members.yml insert app/models/member.rb route devise_for :members $ rails g devise Admin Running via Spring preloader in process 12249 invoke active_record create db/migrate/20230905012038_devise_create_admins.rb create app/models/admin.rb invoke test_unit create test/models/admin_test.rb create test/fixtures/admins.yml insert app/models/admin.rb route devise_for :admins
作成されたマイグレーションファイルに必要なカラムを追加しマイグレーションする。
$ rails db:migrate
コントローラの作成
deviseのデフォルト設定のまま使用する場合は作成する必要はないが、
deviseのデフォルト設定を変更・追加が必要な場合、この手順でコントローラを作成する。
下記のコマンドを実行する。
$ rails g devise:controllers public #会員用 $ rails g devise:controllers admin #管理者用
上記を実行すると下記のようにファイルが作成される。
$ rails g devise:controllers public Running via Spring preloader in process 29804 create app/controllers/public/confirmations_controller.rb create app/controllers/public/passwords_controller.rb create app/controllers/public/registrations_controller.rb create app/controllers/public/sessions_controller.rb create app/controllers/public/unlocks_controller.rb create app/controllers/public/omniauth_callbacks_controller.rb $ rails g devise:controllers admin Running via Spring preloader in process 29914 create app/controllers/admin/confirmations_controller.rb create app/controllers/admin/passwords_controller.rb create app/controllers/admin/registrations_controller.rb create app/controllers/admin/sessions_controller.rb create app/controllers/admin/unlocks_controller.rb create app/controllers/admin/omniauth_callbacks_controller.rb
上記を実行すると下記のように注意文が出てくることがありますが、後でルーティングを設定する際に変更するため、
この段階では気にしなくて良いです。(※1)
(※1)コントローラの作成時に下記のような注意文が出る。
Some setup you must do manually if you haven't yet: Ensure you have overridden routes for generated controllers in your routes.rb. For example: Rails.application.routes.draw do devise_for :users, controllers: { sessions: 'users/sessions' } end
上記を直訳すると、
まだセットアップしていない場合は、手動でセットアップする必要があります: routes.rbで生成されたコントローラのルートをオーバーライドしていることを確認してください。 例えば下記のようなコードにしてください。
となります。この段階では、このようにオーバーライドした形になっていないため、後で記述を変更します。
ビューの作成
次に、会員・管理者用の VIew ファイルを作成します。下記のコマンドを実行する。
$ rails g devise:views publics #会員用 $ rails g devise:views admins #管理者用
上記を実行するとファイルが作成される。作成ファイルが多いため、記述は省略する。
ここで作成されたファイル名(publicsとadmins)をコントローラ名と同じに変更する。 (コントローラをpublics、adminsで作成しても良いが、名称を同じにしないと、uninitialized constantエラーが発生するため、注意)
publics → public admins → admin
この記述に伴い、ビューのフォルダ内記述を変更する。(publics→public、admins→adminに変更)
例: views/public/registrations/new.html.erb
[変更前] <%= render "publics/shared/links" %> [変更後] <%= render "public/shared/links" %>
ルーティングの記述
次にルーティングを記述していく。
現在は下記のようなルーティングとなっている。
config/routes.rb
Rails.application.routes.draw do devise_for :admins devise_for :members end
先ほども記述したようにこの状態では、作成したコントローラの記述を変更したとしてもその処理を実行することができない。
また、今回はURLも変更するため、この状態では変更することがでない。
そのため、下記の記述に変更していきます。
config/routes.rb
Rails.application.routes.draw do # 会員用 devise_for :members, controllers: { registrations: "public/registrations", passwords: 'public/passwords', sessions: 'public/sessions' } # 管理者用 devise_for :admin, skip: [:registrations, :passwords] ,controllers: { sessions: "admin/sessions" } end
上記のように記述します。
今回の場合、管理者側では、ログイン機能のみを作成するため、
skipオプションを使用して不要なルーティングを削除しています。
ルーティングの確認。
$ rails routes
上記のように管理者側では、ログイン機能のみのルーティングが作成されます。
不要な記述の削除
ルーティング作成時に管理者側では、ログイン機能のみを実装しましたが、
この状態では、デフォルトのビューに必要ない機能の記述があるため、リンク先がないなどのエラーが発生します。
そのため、管理者側のログイン機能以外の記述を削除していきます。
app/views/admin/shared/_links.html.erb
<%- if controller_name != 'sessions' %> <%= link_to "Log in", new_session_path(resource_name) %> <% end %> --------------------------------ここから削除-------------------------------- <%- if devise_mapping.registerable? && controller_name != 'registrations' %> <%= link_to "Sign up", new_registration_path(resource_name) %> <% end %> <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> <%= link_to "Forgot your password?", new_password_path(resource_name) %> <% end %> <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %> <% 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) %> <% 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 %> <% end %> <% end %> --------------------------------ここまで削除--------------------------------
上記で記述を削除完了し、サーバーにアクセスすると、ログイン画面が表示される。
以上。