platanus / activeadmin_addons

Extends ActiveAdmin to enable a set of great optional UX improving add-ons
MIT License
761 stars 288 forks source link

[BUG] Formtastic::UnsupportedEnumCollection #504

Open patdec opened 1 month ago

patdec commented 1 month ago

Describe the bug

Since v1.10.0, when I want to display an ActiveAdmin index page containaing a select filter with 'multiple' option enabled, an exception is raised:

Formtastic::UnsupportedEnumCollection

example of input invoking this error:

ActiveAdmin.register User do
filter :role, as: :select, collection: proc { role_options }, multiple: true
end

With previsous version 1.9.0, it works without issue.

Expected behavior A clear and concise description of what you expected to happen.

Screenshots image

Additional context

The bug is related to this method https://github.com/platanus/activeadmin_addons/blob/master/lib/activeadmin_addons/support/select_filter_input_extension.rb#L3:

def collection_from_enum?
  klass.respond_to?(:defined_enums) && klass.defined_enums.has_key?(method.to_s)
end

it overrides the one from Formtastic https://github.com/formtastic/formtastic/blob/master/lib/formtastic/inputs/base/collections.rb#L127

def collection_from_enum?
   object.respond_to?(:defined_enums) && object.defined_enums.has_key?(method.to_s)
end

object is a Ransack object without method defined_enums defined. And for this reason, it works:

[124, 133] in /var/home/patrice/.rbenv/versions/3.3.3/lib/ruby/gems/3.3.0/gems/formtastic-5.0.0/lib/formtastic/inputs/base/collections.rb
   124:           end
   125:         end
   126: 
   127:         def collection_from_enum?
   128:           debugger
=> 129:           object.respond_to?(:defined_enums) && object.defined_enums.has_key?(method.to_s)
   130:         end
   131: 
   132:         def collection_for_boolean
   133:           true_text = options[:true] || Formtastic::I18n.t(:yes)
(byebug) object
Ransack::Search<class: Project, base: Grouping <combinator: and>>
(byebug) collection_from_enum? && multiple?
false

But with klass, it's the User class that invoked and it fails:

[1, 10] in /var/home/patrice/.rbenv/versions/3.3.3/lib/ruby/gems/3.3.0/gems/activeadmin_addons-1.10.0/lib/activeadmin_addons/support/select_filter_input_extension.rb
    1: module ActiveAdminAddons
    2:   module SelectFilterInputExtension
    3:     def collection_from_enum?
    4:       debugger
=>  5:       klass.respond_to?(:defined_enums) && klass.defined_enums.has_key?(method.to_s)
    6:     end
    7: 
    8:     def collection
    9:       if !options[:collection] && collection_from_enum?
   10:         EnumUtils.options_for_select(klass, method.to_s, use_db_value: true)
(byebug) klass
User(id: integer,....................)
(byebug) klass.respond_to?(:defined_enums)
true

Why the original method had been overriden ? Especially, why the receiver is the class method and not the object ?

rjherrera commented 1 month ago

I haven't reviewed it thoroughly but when implemented in #442 the reason given was that formtastic solution with translations worked fine for inputs but not for filters.

One thing to notice is that the version you are referencing (5.0) seems newer to what is installed here (4.0), so that may be something to look at.

I'll take a look when I get a bit of time, but if you want to dig deeper, feel free! Thanks for the report.