Search code examples
ruby-on-railsactiveadmin

Rails ActiveAdmin batch_action with form causing assets:precompile error


We use Rails ActiveAdmin and we are hitting strange asset compiling error. The error causes our rspec CI job to fail in github. It's failing with a database connection error like so:

Run bundle exec rake assets:precompile rake aborted!
ActiveRecord::DatabaseConnectionError: There is an issue connecting to your database with your username/password, username: root.
Please check your database configuration to ensure the username/password are valid.

So that looks like we've done something stupid with ci database config, but... the strange thing is this error happens only when we try to do a very specific thing in our ActiveAdmin code:

We're trying to add a new "batch_action" with a "form" parameter.

  batch_action :migrate_employees, confirm: 'Select target Organisation:', form: {
    'Select Organisation': Organisation.enabled.not_for_demo.pluck(:name, :id),
    'Remove Validation Number': :checkbox
  } do |ids, inputs|
    notice = "TEST#{ids},#{inputs}"
    redirect_to admin_users_path, notice: notice
  end

The above works nicely in local development. If we take out the "form" parameter then it also works as expected (github builds assets and runs the rspec tests over our whole big codebase) but with that little bit in place it bizarrely decides it no longer knows how to connect to the database during assets:precompile.

Does anyone have any pointers for where we need look to fix this?


Solution

  • Organization is a dynamic selection that needs to be triggered in the moment, but your code is forcing a DB hit every time this line is parsed: 'Select Organisation': Organisation.enabled.not_for_demo.pluck(:name, :id),. It works in development because the app is loaded and has access to your configured development DB, but you should be thinking of it as 'working by accident'. Precompile is trying to build the form, and it's following the instruction in your code to immediately hit the DB and use that result to define a static list of selections. You need to encapsulate your query in a proc to prevent it from firing when you don't need that data.

    This is also mentioned in ActiveAdmin's Batch Action forms documentation:

    When you have dynamic form inputs you can pass a proc instead:

    batch_action :doit, form: -> { {user: User.pluck(:name, :id)} } do |ids, inputs|