🗂️

ちょっと複雑な処理をRailsAdminから実行する

に公開

こんにちは。リンクウェル対面診療システムチームの山本です。
今回はRailsの管理画面を作成してくれるRailsAdminをカスタマイズして、ちょっと複雑な処理をボタンから呼び出す処理を作ってみたいと思います。

初めに

RailsAdminとは

おそらくRuby on Railsが日本で広く使われ始めた2010年代初頭から、開発され続けている管理画面作成ツールです。

https://github.com/railsadminteam/rails_admin

ここで言う管理画面とは利用者が直接利用するものではなく、開発者やシステム管理者が利用するための画面のことです。

そのため、デザインや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_optionFont Awesomeのアイコンを指定する。
    • register_instance_option :controller で指定したブロック内にコントローラー内の処理を書く。

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を再起動する。

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 が利用可能。

完成

Userモデルのタブにボタンが表示されました。

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

まとめ

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

Linc'well, inc.

Discussion