Summary
Calling display_on? on the default :new action item (the one AA registers
automatically for every resource, added in ActiveAdmin::Resource::ActionItems #add_default_new_action_item) raises a NameError because its if: lambda
references active_admin_config, which is not resolvable in the context the
lambda is evaluated from when triggered via display_on?.
Reproduction
ActiveAdmin.register SomeModel do
config.action_items.delete_if do |item|
item.name == :new && item.display_on?(:index)
end
end
Booting a page for SomeModel (or anything that walks config.action_items
and calls display_on?) raises:
NameError: undefined local variable or method 'active_admin_config' for an instance of ActiveAdmin::ActionItem
Root cause (as far as we've traced it)
lib/active_admin/resource/action_items.rb registers the default :new item
with:
add_action_item :new, only: :index, if: -> { new_action_authorized?(active_admin_config.resource_class) } do
...
end
In 3.x, the equivalent visibility check ran inline, evaluated lazily at
render time in a view context where active_admin_config resolves. In
4.0.0.beta22, the check moved into a separate if: lambda that gets
evaluated by ActiveAdmin::OptionalDisplay#display_on? outside that view
context, where active_admin_config is no longer in scope.
Any resource-level code that calls display_on? on the default :new item
(a previously-working, documented pattern for conditionally hiding it) will
hit this.
Environment
- activeadmin 4.0.0.beta22 (gem, from
github.com/activeadmin/activeadmin
at tag v4.0.0.beta22)
- Ruby 3.4.9, Rails 7.2.3
- Reproduced independently of activeadmin_addons or any other gem — bare AA
v4 core against a single custom resource registration.
What we did as a workaround
We dropped the display_on? probe and delete by name only, since the
default :new item is registered only: :index — for the default item,
name == :new && display_on?(:index) and name == :new are equivalent:
config.action_items.delete_if { |item| item.name == :new }
This sidesteps the lambda entirely but obviously doesn't fix the underlying
display_on?/if:-lambda scoping issue for anyone who needs to call
display_on? for a different reason.
Happy to provide more context or a minimal repro repo if useful.
Summary
Calling
display_on?on the default:newaction item (the one AA registersautomatically for every resource, added in
ActiveAdmin::Resource::ActionItems #add_default_new_action_item) raises aNameErrorbecause itsif:lambdareferences
active_admin_config, which is not resolvable in the context thelambda is evaluated from when triggered via
display_on?.Reproduction
Booting a page for
SomeModel(or anything that walksconfig.action_itemsand calls
display_on?) raises:Root cause (as far as we've traced it)
lib/active_admin/resource/action_items.rbregisters the default:newitemwith:
In 3.x, the equivalent visibility check ran inline, evaluated lazily at
render time in a view context where
active_admin_configresolves. In4.0.0.beta22, the check moved into a separate
if:lambda that getsevaluated by
ActiveAdmin::OptionalDisplay#display_on?outside that viewcontext, where
active_admin_configis no longer in scope.Any resource-level code that calls
display_on?on the default:newitem(a previously-working, documented pattern for conditionally hiding it) will
hit this.
Environment
github.com/activeadmin/activeadminat tag
v4.0.0.beta22)v4 core against a single custom resource registration.
What we did as a workaround
We dropped the
display_on?probe and delete by name only, since thedefault
:newitem is registeredonly: :index— for the default item,name == :new && display_on?(:index)andname == :neware equivalent:This sidesteps the lambda entirely but obviously doesn't fix the underlying
display_on?/if:-lambda scoping issue for anyone who needs to calldisplay_on?for a different reason.Happy to provide more context or a minimal repro repo if useful.