リソースクラスを文字列で指定可能に
ActiveAdmin v3では、リソース登録時に resource_class を文字列で渡せるようになりました。これにより、ActiveAdminに紐づく全モデルクラスの事前ロードを回避できるようになります。
背景
これまで ActiveAdmin.register にはクラスオブジェクトを直接渡す必要がありました。この設計では、内部で resource_class.name を呼び出すためだけに、ActiveAdminに登録される全てのモデルクラスが事前にロードされていました。この挙動はActiveRecordの関連付けが文字列でクラス名を指定できる設計と対照的です。
クラスオブジェクトを使う唯一の目的がクラス名の文字列を取得することであり、実際にはクラス本体は後続の処理まで不要であるにもかかわらず、不必要な早期ロードが発生していました。
技術的な変更
lib/active_admin/resource.rb の Resource::Base#initialize メソッドで、クラス名文字列の取得方法が変更されました。
変更前:
@resource_class_name = "::#{resource_class.name}"
変更後:
@resource_class_name = resource_class.respond_to?(:name) ? "::#{resource_class.name}" : resource_class.to_s
respond_to?(:name) による分岐が追加され、クラスオブジェクトの場合は従来通り name メソッドを呼び出し、文字列の場合は to_s でそのまま使用します。これにより以下の両方の書き方が可能になります:
# クラスオブジェクトを渡す(従来の方法)
ActiveAdmin.register Category
# 文字列でクラス名を渡す(新しい方法)
ActiveAdmin.register 'Category'
テストでは spec/unit/namespace/register_resource_spec.rb に文字列指定のケースが追加され、namespace.resources.keys に "Category" が含まれることを確認しています。
設計判断
既存の引数を拡張する方式 が採用されました。新しい引数やオプションを追加せず、resource_class パラメータの型を Class から Class | String に広げる実装です。
PR本文で言及されているように、この設計はActiveRecordの関連付けと同様のパターンを踏襲しています。ActiveRecordでは belongs_to :category と書いても即座に Category クラスがロードされず、実際に必要になるまで遅延されます。
respond_to?(:name) による型チェックのみで実現されており、既存のクラス渡しの挙動は完全に保たれます。ActiveAdminのリソース登録処理は内部的にクラス名文字列しか保持していなかったため、入力段階で文字列を受け取る変更は自然な拡張といえます。
まとめ
本PRは、不要なモデルクラスの早期ロードを排除する変更です。resource_class の型を Class | String に拡張することで、ActiveRecordと同様の遅延ロードパターンを実現し、アプリケーション起動時のメモリ効率を改善しています。