こんにちは!kossyです!
今回はactiveadminでローカル環境に管理者権限を付与するやり方をブログに残したいと思います。
activeadminはRailsアプリケーションに簡単に管理者画面を実装できるgemです。
前提
Userモデル、及びusersテーブルに一つ以上レコードがあることを前提に話を進めます。
以下、導入手順です。
方法
Gemfileへの追加
Gemfile gem 'activeadmin'
コマンドの実行
ターミナル(userモデルが作成済みの場合)
$ rails g active_admin:install --skip-users
ここでrails db:migrateするところですが、
このまま実行するとactive_admin_commentsというテーブルが作成されますので、
コメントテーブルが不必要ということであれば、マイグレーションファイルを削除してください。
管理者画面にコメントモデルを表示させないようにする処理
config/initializers/active_admin.rb # == Admin Comments # # This allows your users to comment on any resource registered with Active Admin. # # You can completely disable comments: # config.comments = false # # You can change the name under which comments are registered: # config.comments_registration_name = 'AdminComment' # # You can change the order for the comments and you can change the column # to be used for ordering: # config.comments_order = 'created_at ASC' # # You can disable the menu item for the comments index page: config.comments_menu = false <=ここのコメントアウトを外す #
サーバーを再起動し、ポート番号/adminにアクセスすると、
上記のような画面が表示されると思います(ヘッダーにアプリ名、モデル名が並びます)
次に、管理者画面から、ユーザー管理ができるようにカスタマイズします。
権限の管理を行うためにUserモデルにroleというカラムを追加します。
roleカラムの追加
$ rails g migration AddRoleToUser role:integer
マイグレーションファイルを編集
db/migration/2018XXXXXXXXXX_add_role_to_user.rb class AddRoleToUser < ActiveRecord::Migration[5.1] def change add_column :users, :role, :integer, null: false, default: 0 end end
$ rails db:migrate
adminの場合、管理者権限が付与されますので、マイグレーションファイルでは
roleのデフォルト値を0(通常のuserの権限)としています。
app/models/user.rb
enum role: { user: 0, admin: 1 }
ステータス管理をしやすくするためにenum(列挙型)でデータを定義します。
これで0や1に意味を付与でき、可読性が向上します。
これでモデル側の準備は完了です。
次に、権限の制御のロジックを組みます。
authenticate_admin_user!メソッドの有効化
config/initializers/active_admin.rb # == User Authentication # # Active Admin will automatically call an authentication # method in a before filter of all controller actions to # ensure that there is a currently logged in admin user. # # This setting changes the method which Active Admin calls # within the application controller. config.authentication_method = :authenticate_admin_user! <=ここのコメントアウトを外す
application_controller.rbにauthenticate_admin_user!メソッドを定義
同時に例外処理も記述
app/controllers/application_controller.rb rescue_from SecurityError do |exception| redirect_to root_path, notice: '管理者画面へのアクセス権限がありません!' end protected def authenticate_admin_user! raise SecurityError unless current_user.try(:admin?) end
これで、管理者権限のないユーザーが管理者画面へのアクセスを試みた場合に、ルートパスへリダイレクトされるようになります。
次に、pryでユーザーのロールをadminに変更します。
consoleで権限の変更
$ rails c [1] pry(main)> User.first.update_attributes(role: :admin) [2] pry(main)> User.first.role 実行結果=> "admin" [3] pry(main)> User.first.admin? 実行結果=> true
上記でロールにadminを指定したユーザでログインを行い、再度ポート番号/adminにアクセスして、
activeadminの管理者ページが表示されれば、ユーザの権限管理は完了です。
2018/09/29 追記
なぜか上記のやり方でrails cで管理者権限を追加できなくなっちゃいました、、、
[1] pry(main)> User.first.admin? (0.5ms) SET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483 User Load (0.3ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 => false [2] pry(main)> User.first.role User Load (0.4ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 => "user" [3] pry(main)> User.first.update_attributes(role: :admin) User Load (0.4ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 (0.2ms) BEGIN User Exists (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY '12345678@gmail.com' AND (`users`.`id` != 1) LIMIT 1 (0.1ms) ROLLBACK => false
カラムの更新方法について、
sakurawi.hateblo.jp
こちらの記事を参考に、
[5] pry(main)> User.first.update_columns(role: :admin) User Load (0.4ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 SQL (12.7ms) UPDATE `users` SET `users`.`role` = 1 WHERE `users`.`id` = 1 => true [6] pry(main)> User.first.admin? User Load (0.4ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 => true [7] pry(main)> User.first.role User Load (0.4ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 => "admin"
できた!!!
もしupdate_attributesでロールの更新ができなければ、
update_columnsを試してみてください!
参考にさせていただいた記事
update_attributesとupdate_columnsの違い【Ruby on Rails】 - SakuraWi - BLog