管理ページを簡単に追加できる ActiveAdmin はとても便利なんだけれど、ここはちょっとね?と思わせる仕様がたまにあります。
現時点(2015/01/26)で最新の1.0.0preのサイドバーの検索条件もそのひとつ。
ここの検索条件には、デフォルトでモデルのアソシエーションが追加される仕様になっています。
たいていそこそこアソシエーションの多い user モデルなどの場合、N+1 問題か?ってくらいページが重くなり、まともに開けないレベルになったりするんですね。
filter
メソッドを使って必要な条件だけを追加したり、remove_filter
で不必要な条件を削除したりは出来るのだけど、そもそも has_many
や has_one
はどのモデルでも基本的に検索条件としては必要ないので、モンキーパッチを当ててデフォルトの検索条件そのものを変えることにしました。
module ActiveAdmin
module Filters
# lib/active_admin/filters/resource_extension.rb
# サイドバーの検索条件から、default_association_filters を対象外にする。
# has_manyやhas_oneがプルダウン条件になって恐ろしく重くなる現象の回避策。
module ResourceExtension
# Returns a default set of filters for the associations
def default_association_filters
if resource_class.respond_to?(:reflect_on_all_associations)
poly, not_poly = resource_class.reflect_on_all_associations.
select{ |rr| rr.macro == :belongs_to }.partition{ |r| r.options[:polymorphic] }
# remove deeply nested associations
not_poly.reject!{ |r| r.chain.length > 2 }
filters = poly.map(&:foreign_type) + not_poly.map(&:name)
filters.map &:to_sym
else
[]
end
end
end
end
end
belong_to
はそのまま検索条件としてほしいので、アソシエーションのうちこれだけはデフォルトで追加されるようにしています。
もちろんこのモンキーパッチで定義された検索条件はただのデフォルトなので、 個々のモデルに対して filter
メソッドで条件を後から定義し直したりすることもできます。
上記のイニシャライザを追加したら、サーバを再起動すると反映されます。
参考にしたのはこちらのissueです。
Large associations cause long load times with default filters #2738
一応対策はされるようなので、早く公式に設定が追加されると良いですね。