Use ActiveAdmin like a boss

Use ActiveAdmin like a boss

ActiveAdmin is widely used administration framework in Rails applications. This post explains how to hook more sophiscicated domain logic into it.

An ActiveAdmin resource can be generated to perform CRUD operations on the application’s models. However, there are scenarios where:

  • business logic is no longer a part of the model and it lives somewhere else, eg. service, aggregate
  • it is not desired to remove the data, but instead set a status, eg. “Cancelled”
  • admin need super powers which are not living in the ActiveRecord model (like in the first item)

Taking this into account, classic CRUD approach is simply not enough. Below, there’s a short example extracted from sample Order management app

ActiveAdmin.register Order do
  controller { actions :show, :index, :cancel }

  member_action :cancel, method: %i[post] do
    command_bus.(
      Ordering::CancelOrder.new(order_id: Order.find(params[:id]).uid),
    )
    redirect_to admin_orders_path, notice: 'Order cancelled!'
  end

  action_item :cancel,
              only: %i[show],
              if: proc { 'Submitted' == resource.state } do
    link_to 'Cancel order',
            cancel_admin_order_path,
            method: :post,
            class: 'button',
            data: {
              confirm: 'Do you really want to hurt me?',
            }
  end
end

What’s happening here:

One can say β€” but it’s just a status column update. Nope, that tiny column update is a result of business operation taking specific constraints into account. Moreover, data remain consistent because there’s no longer a possibility to “just” update the column or many of them. That updated column is a representation in read model which is not meant to deliver domain behaviour, only data for display β€” Implementing Domain-Driven Design, Vaughn Vernon.

I find this useful, especially if one wants to avoid multiple checks and conditions (eg. IF statements) in code to determine whether certain actor (admin in our scenario) is capable of doing certain operation.

Now, a plug πŸ”Œ. Join ARKADEMY.DEV and get access to our best courses: Rails Architect Masterclass, Anti-IF course, Blogging for busy programmers, Async Remote, TDD video class, Domain-Driven Rails video course and growing!

You might also like