railsadminteam / rails_admin

RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data
MIT License
7.88k stars 2.25k forks source link

Make reusable action configuration autoload-friendly #3518

Open Cardyard opened 2 years ago

Cardyard commented 2 years ago

Is your feature request related to a problem? Please describe. It took me a while to get autoloading working with Zeitwerk and Rails 7 and Rails Admin 3.0. I've ended up with the opposite of what I had pre: Zeitwerk/Rails 7/Rails Admin 3.0..

Describe proposed solution(s) Add some comments to... Configuration 2. Actions

These are my proposed comments...

Reloading with Zeitwerk

If you are defining reusable rails_admin actions in zeitwerk mode(the only mode post Rails 6), you can include your library of code in the main autoloader in config/application.rb, but must register your rails_admin actions only once. This can be achieved using the after_initialize block

# config/initializers/rails_admin.rb
# Define asset_source outside the `after_initialize' block so it is run before the gem initializer and avoid getting an error
RailsAdmin.config { |config| config.asset_source = :sprockets } # or :webpacker
Rails.application.config.after_initialize do
  # Require your reusable actions which will have the line RailsAdmin::Config::Actions.register(self) 
  Dir[Rails.root.join('lib', 'rails_admin','config','actions','*.rb')
    ].each do |file|
    require file
  end
  RailsAdmin.config do |config|
       dashboard
      index
      new
      export
      bulk_delete
      show
      edit
      <your actions here>
      delete
      show_in_app
  end
end

Avoid using to_prepare block as an alternative to after_initialze because the to_prepare block will be run again after unloading classes by the autoloader which results in rails_admin actions and models being removed from the router.

Note that require is discouraged as you should allow the autoloader to manage loading your code, and using require will exclude the required file from the autoloader. However, since rails_admin actions can't be reloaded, its fine/preferable to use require. Any code you wish to be reloadable can, of course, be placed in other files.

mshibuya commented 2 years ago

Any code in a reusable action is not reloaded

They are not reloaded because the action need to be explicitly require -ed and is not autoloaded with the current way. So I want to think about the better way to handle custom actions, which is more friendly for autoloading.

Cardyard commented 2 years ago

The problem I had making a reusable action reloadable, is Zeitwerk unloads before reloading, and unloading a reusable action appears to remove it from the router. I'm happy with the way it works as the reusable actions should be kept simple, and any code held in services etc which are reloadable.