ActiveAdmin で一度入力した input を disabled にする


はじめに

ActiveAdmin でユニーク性を保ちたい変数については、一度作成済みのときは値は確認したいが、編集時は間違えて変更してしまわないように編集不可にしたいといった要望がありました。
しかし、ActiveAdmin の form は編集、作成で共有しているので、編集時のみ disabled にするといったことができません。
そこで今回は、 ActiveAdmin::Views::ActiveAdminForm を拡張することでそのような特殊な input を実現できたので紹介します。

ActiveAdmin::Views::ActiveAdminForm に protected_input を拡張する

以下のように、 ActiveAdmin::Views::ActiveAdminForm に新しく protected_input を追加します。

lib/active_admin/views/active_admin_form.rb
module ActiveAdmin
  module Views
    class ActiveAdminForm
      def protected_input(*args)
        atr, option = args
        append_option = object.persisted? ? { input_html: { disabled: true } } : {}
        args[1] = option.to_h.merge(append_option)
        input(*args)
      end
    end
  end
end

作成したクラスは、 require するのを忘れないようにしましょう。

ActiveAdmin.setup do |config|
  # 省略

  Dir["#{Rails.root}/lib/active_admin/**/*.rb"].each { |lib| require lib }

end

使い方

実際の使い方は以下のようになります。

  form do |f|
    f.inputs Item do
      f.protected_input :user
      f.input :name
    end
    f.actions
  end

すると、以下のように編集時には入力項目を disabled を切り替えられていることが確認できます。

さいごに

最初は、admin配下のファイルにprotected_inputに書いてあるような分岐を書いていたのですが、メソッドが拡張できると読みやすさを維持できていい感じです。
ドキュメントにない使い方ですが、ソースを読んで動作を理解できれば、気軽にメソッド拡張ができるのもRubyのいいところですね。