ちょっと複雑な処理をRailsAdminから実行する
こんにちは。リンクウェル対面診療システムチームの山本です。
今回はRailsの管理画面を作成してくれるRailsAdminをカスタマイズして、ちょっと複雑な処理をボタンから呼び出す処理を作ってみたいと思います。
初めに
RailsAdminとは
おそらくRuby on Railsが日本で広く使われ始めた2010年代初頭から、開発され続けている管理画面作成ツールです。
ここで言う管理画面とは利用者が直接利用するものではなく、開発者やシステム管理者が利用するための画面のことです。
そのため、デザインやUIが簡素なものになっていますが、専用の画面を作り込まなくてもデータを直接操作できるため、開発スピードを求められる現場では昔から広く使われています。
もちろんDBのCRUD操作だけではなくカスタマイズも可能です。具体的には config/initializers 以下にデフォルトで設置される rails_admin.rb を起点として処理を書いていくこととなります。あまりプラガブルな作りとは言えず、RailsAdminの内部を理解していないと思い通りの画面を作っていくのは難しい印象です。
前提
RailsAdminは正常にセットアップされ、RailsAdmin上でのModel編集はできる状態となっているものとします。
登場するモデルは2つです。
- Clinic
- 複数拠点展開しているクリニックのイメージです。
- ClinicUser
- クリニックで働く医師や看護師のイメージです。
このようなデータモデルは、複数院のDX支援をしている弊社ならではかもしれません。クリニックに勤務するユーザーのロールによっては、複数のクリニックを担当するケースもありえます。イメージが湧きにくければ、チェーン店のエリアマネージャーや社員を想像してみてください。
テーブルとその関係は以下のとおりです。
clinic_users は中間テーブル clinic_memberships を介して複数の clinics に所属します。
ゴール
管理画面とはいえ、DBの値を触るだけではなく一連のデータ処理を行いたいこともあるかと思います。メンテナンスのたびに rails console を使うのは非効率ですので、画面からモデルの特定のメソッドを呼び出すような処理を追加してみたいと思います。今回はクリニックユーザーを一括してクリニックに紐付ける処理を作ってみます。

カスタマイズの手順
カスタマイズした設定ファイルを設置
ここでは lib/rails_admin/config/actions/clinic_memberships_bulk_association.rb に設置します。
require 'rails_admin/config/actions'
require 'rails_admin/config/actions/base'
module RailsAdmin
module Config
module Actions
class ClinicMembershipsBulkAssociation < RailsAdmin::Config::Actions::Base
RailsAdmin::Config::Actions.register(self)
register_instance_option :member? do
true
end
register_instance_option :http_methods do
%i[get post]
end
register_instance_option :link_icon do
'fas fa-sitemap'
end
register_instance_option :controller do
proc do
if request.get?
@clinic_user = @object
render :clinic_memberships_bulk_association
elsif request.post?
# 全クリニックへの一括紐づけ
@clinic_user = ClinicUser.find(params[:id])
Clinic.all.each do |clinic|
@clinic_user.clinic_memberships.find_or_create_by(clinic_id: clinic.id)
end
redirect_to_on_success
end
end
end
end
end
end
end
- ポイント
- IDが必要なルーティングは
register_instance_option :member?にtrueを設定する。 -
register_instance_optionにFont Awesomeのアイコンを指定する。 -
register_instance_option :controllerで指定したブロック内にコントローラー内の処理を書く。
- IDが必要なルーティングは
RailsAdminの設定ファイルから呼び出す
config/initializers/rails_admin.rb から、さきほど記載したカスタマイズ設定ファイルを指定します。
# !!!ここに追加!!!
require Rails.root.join('lib/rails_admin/config/actions/clinic_memberships_bulk_association')
RailsAdmin.config do |config|
config.asset_source = :sprockets
### Popular gems integration
## == Devise ==
# config.authenticate_with do
# warden.authenticate! scope: :user
# end
# config.current_user_method(&:current_user)
## == CancanCan ==
# config.authorize_with :cancancan
## == Pundit ==
# config.authorize_with :pundit
## == PaperTrail ==
# config.audit_with :paper_trail, 'User', 'PaperTrail::Version' # PaperTrail >= 3.0.0
### More at https://github.com/railsadminteam/rails_admin/wiki/Base-configuration
## == Gravatar integration ==
## To disable Gravatar integration in Navigation Bar set to false
# config.show_gravatar = true
config.actions do
dashboard # mandatory
index # mandatory
new
export
bulk_delete
show
edit
delete
show_in_app
## With an audit adapter, you can add:
# history_index
# history_show
clinic_memberships_bulk_association do
visible do
# どのモデルにタブを表示させるかを指定
bindings[:abstract_model].model.to_s == 'ClinicUser'
end
end
end
end
- ポイント
- 追加タブを表示したいModelを
visibleのブロックに記載する。 - initializers以下のファイルを編集した後は、railsを再起動する。
- 追加タブを表示したいModelを
Viewを追加する
今回は以下の場所に設置しました。内容は単純でボタンを押すとPOSTするだけです。
app/views/rails_admin/main/clinic_memberships_bulk_association.html.erb
<%= form_for(@clinic_user.name, url: clinic_memberships_bulk_association_path(model_name: 'ClinicUser', id: @clinic_user.id)) do |f| %>
<%= f.submit '実行' %>
<% end %>
- ポイント
- RailsAdminが生成する名前付きルート
clinic_memberships_bulk_association_pathが利用可能。
- RailsAdminが生成する名前付きルート
完成
Userモデルのタブにボタンが表示されました。

UserモデルのindexにはFont Awesomeで指定したアイコンが表示され、追加機能に直接アクセスできます。

まとめ
今回はModelに対して単純な処理を行うボタンを追加してみました。
アプリケーションの調査や保守作業で rails console を使うことがあるかと思いますが、定型的な処理はボタンにすることで容易にRailsAdminから実行できます。
RailsAdminを使っており、保守でよく使うコマンドがある場合は、タブ内に機能を組み込むことを検討してみましょう。
Discussion