active_adminで管理画面を作ってみた

f:id:endoakak:20200725103845j:plain

アプリに管理人用画面を追加しました。ユーザーの一覧や投稿の一覧が表示されて、編集したりもできるページです。

思ったよりかなり苦労しました。

管理画面の作り方いろいろ

Railsアプリでの管理画面の作り方は主に4種類です。

  • rails_admin

  • active_admin

  • administrate

  • 自分で1から作る

上3つはgemです。

rails管理画面系gem比較してみた - Qiita

こちらにまとめてくれているのですが、rails_adminとactive_adminは割と簡単で、administrateはカスタマイズしたい人向け、という感じだと思います。

私は今回、active_adminを使いました。初めはrails_adminを試したのですが、エラーになって解決できそうになかったのでactive_adminに乗り換えました。

前提

私は今回、Userモデルを含めモデルをいくつか作成して、アプリとしての機能は概ね出来上がった状態から、管理画面の追加をしています。アプリを作り始める段階で管理画面機能をつける場合とは、多少違うところがあるかもしれないです。

gemのインストール

まずはgemをインストールします。deviseはお好みで。

gem 'activeadmin'
gem 'devise'


% bundle install

流石にここまではいいのですが、このあとが少しややこしい。

# deviseを使いたくない場合
bundle exec rails g active_admin:install --skip-users
# すでに作ってあるUserクラスを使用する場合
bundle exec rails g active_admin:install User
# それ以外。Deviseと連携してAdminUserクラスが作られる
bundle exec rails g active_admin:install

私はすでにdeviseでUserを作っていたので二つ目を選びましたが、そうするとルーティングが勝手に変わったりして、いろいろとよくわからないことになりました。

どこまで影響が出ているのかわからなくなったのでいったんリセットして(GitHub便利だな〜)、一つ目の--skip-usersを行いました。今度はactive_adminは余計なことをせずに、必要なファイルだけ作成してくれました。

f:id:endoakak:20200904185005p:plain

ファイルがいくつか生成されました。マイグレーションファイルも生成されるので、マイグレーションをしておきます。

管理画面でのコメント機能に関わるものじゃないかと思うのですが、今回は別に必要ないのであまり気にしてないです。

% rails db:migrate

モデルごとに設定

実はこの時点ですでに、localhost:3000/adminにアクセスすれば管理画面が表示されます。しかしテーブルは表示されていないので、これからモデルごとに設定を行なっていきます。

各モデルについて、以下のコマンドを実行します。

% rails g active_admin:resource モデル名

すると、app/admin/モデル名s.rbというファイルが生成されます。

permit_params :name, :email, ...

という行があるのでコメントアウトを外します。

これで管理画面にテーブルが表示され、編集や削除ができるようになります。

アクセス制限

管理画面自体はこれでできたのですが、このままでは誰でもアクセスできてしまうので、アクセスを制限する必要があります。

アクセス自体を制限するだけでなく、ユーザーによって操作できることに制限をつける、というのも可能みたいです。

cancancanを使うとかusersテーブルに管理者か判断するためのカラムを足すとかいろいろやり方はありそうでしたが、私はBASIC認証でアクセス自体を制限することにしました。

アクセスを制限するには、config/initializer/active_admin.rb内のController Filtersという項目を探して、config.before_action :do_something_awesomeコメントアウトを解除します。

そして、do_something_awesomeの代わりにauthenticate_adminと記述します。

# == Controller Filters
#
# You can add before, after and around filters to all of your
# Active Admin resources and pages from here.
#
config.before_action :authenticate_admin

次に、app/controllers/application_controller.rbで、authenticate_admin!メソッドを定義します。

def authenticate_admin
  authenticate_or_request_with_http_basic do |username, password|
    username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]
  end
end

これで、管理画面へのアクセスにはBASIC認証がかかるようになりました。

assetsの移動

最後にもう一つ。管理画面と直接の関係はないですが、active_adminを入れたことでcssなどが干渉してビューが崩れるという問題が発生します。迷惑極まりないので、active_admin関連のアセットファイルを隔離しておきます。

これについては、この記事の通りにやったらできました。

active_adminのCSS/JavaScript置き場 - Qiita

app/assetsにjavasccriptsというフォルダやstylesheetsディレクトリの中にactive_admin.cssというファイルがあります。それらをそれぞれvendor/assets/javascripts/active_admin.jsvendor/assets/stylesheets/active_admin.scssとなるように移動させます。

その後、config/applicatin.rb

config.assets.paths << config.root.join("vendor/assets/javascripts")
config.assets.paths << config.root.join("vendor/assets/stylesheets")

config/initializers/active_admin.rb

config.clear_stylesheets!
config.register_stylesheet 'active_admin.css'

config.clear_javascripts!
config.register_javascript 'active_admin.js'

という記述を追加したら、cssの干渉がなくなりました。めでたし。

まとめ

  • Railsアプリで管理画面を作る方法はいろいろある
  • active_adminを使うとわりと簡単に作れる
  • 管理画面を作った後はアクセスの制限が必要
  • active_adminのcssが干渉してくるので、アセットファイルを移動することが必要