DarinH
DarinH

Reputation: 4889

Calling a controller function to define a menu in ActiveAdmin

I've got the following code in an activeadmin resource controller....

ActiveAdmin.register Customer do
  menu :parent => "Accounts", :label => proc{controller.get_label()}

  controller do
    def get_label
      current_user.hasrole?(:sysadmin) ? 'Customers' : 'Your Account'
    end

This doesn't work. I get a "get_label not defined on CustomersController" error. However, I do have the get_label function defined on the controller, as you can see above.

Anyone have any idea how to setup a call like this (basically to dynamically determine the label to use for the customers menu item, based on the current user roles)?

Upvotes: 1

Views: 1847

Answers (1)

masahji
masahji

Reputation: 544

The proc that you are using for :label is going to be evaluated in the context of the view. In order to access its controller you can call self.controller which is what you are doing. The problem is that

menu :parent => "Accounts", :label => proc{controller.get_label()}

affects the view on all of the generated ActiveAdmin controllers (because the menu is a nav in ActiveAdmin that exists everywhere). So for example, if you pull up the Dashboard, controller will be an instance of Admin::DashboardController (but get_label is defined in your generated Admin::CustomerController, so you get an error). You have a couple of sane choices here.

1) put get_label in a helper, like application_helper and then do `proc { get_label }

2) put get_label in ApplicationController. In this case your call to menu doesn't change.

You can do a bunch of other things to make this nicer but they are mostly just variations of the two options above.

Why is a method in ApplicationController (app/controllers/application_controller.rb) available to my ActiveAdmin controllers?

It turns out that when ActiveAdmin generates your controller it has the following inheritance structure:

  Admin::DashboardController # generated from app/admin/dashboard.rb
    extends ActiveAdmin::PageController 
      extends ActiveAdmin::BaseController 
        extends InheritedResources::Base 
          extends ApplicationController # application_controller.rb

Therefore, instance methods defined under ApplicationController will be available to Admin::DashboardController

Hope this helps

Upvotes: 1

Related Questions