5 Impossibly easy solutions for ActiveAdmin and ForestAdmin [Code + Guide]
I’ve always been fascinated by Rubik’s cubes, how impossibly hard it has been for me to solve one, until I finally looked up the solution. Unlike many problems, a Rubik’s cube won’t really give you headaches. But it shares this thing in common with many problems, that once you know the solution, they almost disappoint by how easy and unchallenging they become.
I spend my days in the Admins of companies in the making, and as a mostly Rails developer, some Rails frameworks used most of the time got my attention. Very often, the same, simple questions arise on perceived limitations, that have incredibly easy workarounds.
I want to give solutions with ActiveAdmin and ForestAdmin to 5 Admin customization challenges that give headaches to some developers.
1- 💡 Showing values from my DB isn’t enough. How do I show computed values in my tables?
Computed values are used for several different purposes. It can be as simple as humanizing DB attributes to make them User-friendly, or they can be more complex use-cases and use relationships/associations to display sums of records, contextual labels, rankings… And else. :)
ActiveAdmin
With ActiveAdmin, computed on the fly values are called ‘status tags’ and are shown as read-only values. You can simply declare them when you register your resource:
status_tag 'In Progress'
# => <span class='status_tag in_progress'>In Progress</span>
status_tag 'active', class: 'important', id: 'status_123', label: 'on'
ForestAdmin
In Forest, “Smart Fields” do the same but can also be read-write instead of read-only. What’s more, Smart Fields can appear in both Index and Show views:
class Forest::User
include ForestLiana::Collection
collection :users
field :fullname, type: ‘String’ do
“#{object.firstname} #{object.lastname}”
end
end
2- 👩👦👦 How do I make forms for “has_many” associations work?
Has_many / belongs_to associations can be tricky to handle in ActiveAdmin. Let’s take the example of a class Multinational
has_many Offices
, and you would like to manually create new Offices
belonging to a Multinational
from its details view.
ActiveAdmin
“Nested forms” do the trick. Add one to the view when registering the parent model:
ActiveAdmin.register Multinational do
permit_params :name, :employees_number
form do |f|
### Declare here the model's own form fields:
f.inputs "Details" do
f.input :name, label: "Company Name"
f.input :employees_number, label: "Number of Employees"
end
### Declare here the form for the child model, using the "has_many" method:
f.inputs "Offices" do
f.has_many :offices, heading: false do |o|
o.input :location, label: "City Name"
o.input :opened_at, :as => :datetime_picker
end
end
f.actions
end.
.
.end
ForestAdmin
With Forest you can use a Smart Action to do this, which adds flexibility as you can add a layer of logic which you will have to write in the controller. All the other fields can be hidden or shown by using the GUI layout editor in Edit Layout mode.
class Forest::Multinational
include ForestLiana::Collection
collection :offices
action 'Create', fields: [
{ field: 'location', type: 'String', isRequired: true},
{ field: 'opened_at', type: 'Date'}
]
end
3- ⛔️ My Admin users keep touching/editing data that they shouldn’t touch. How can I keep them away?
Seeing critical data being lost because of a misuse of the Admin interface is upsetting.
ActiveAdmin
To protect your resources, add a call to actions
to the ActiveAdmin resource that needs to be protected, and remove editing and/or deletion actions:
ActiveAdmin.register Office do
actions :all, :except => [:destroy]
.
.
.
end
What if you want to make your data read-only? In this case, you just need to explicitly declare only the actions you want to allow:
ActiveAdmin.register Office do
actions :index, :show
.
.
.
end
The main downside being that this disables the option for all users, but developers can of course keep accessing data through the good old console.
ForestAdmin
Forest handles this without code, directly from the UI. Hide or show the fields through the Layout Editor and use the team based permissions to manage access. In the “Settings” tab select “Teams” to create a group of users, and give the appropriate rights in the “Users” tab.
4- ⚙️ Help, my Admin is ugly / I don’t have enough UI features — Customizing the admin template.
ActiveAdmin
Customize the ActiveAdmin layout is made annoyingly hard as it is not actually defined as a layout file, but is generated programatically. Placing a custom layout in the layout directory will therefore not actually override the default layout.
A solution on StackOverflow however gives a workaround:
You can, however, monkey-patch or duck-punch the active admin layout methods inside your application.
The following will add an ie-specific stylesheet to the header:
module ActiveAdmin
module Views
module Pages
class Base < Arbre::HTML::Document
alias_method :original_build_active_admin_head, :build_active_admin_head unless method_defined?(:original_build_active_admin_head)
def build_active_admin_head
within @head do
meta :"http-equiv" => "Content-type", :content => "text/html; charset=utf-8"
insert_tag Arbre::HTML::Title, [title, active_admin_application.site_title].join(" | ")
active_admin_application.stylesheets.each do |path|
link :href => stylesheet_path(path), :media => "screen", :rel => "stylesheet", :type => "text/css"
end
active_admin_application.javascripts.each do |path|
script :src => javascript_path(path), :type => "text/javascript"
end
text_node csrf_meta_tag
text_node "<!--[if lt IE 7]>
<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"admin_ie7.css\ />
<![endif] -->".html_safe
end
end
end
end
end
end
ForestAdmin
Forest allows to plug standard EmberJS components in place of its standard views (Called “Smart Views”). In Edit Layout mode, select a view you want to customize and click on the ⚙️ icon. Select the “Smart View” tab, and insert your own code (or choose code from the library of already available components).
5- ♻️ How do I make my forms dynamically change depending on what is needed by the Admins?
In Rails, you can implement dynamic changes in your views by using embedded ruby, or rendering different views depending on the context.
ActiveAdmin
With ActiveAdmin, you can’t directly edit views, but you can make the changes programmatically in the ‘register’. The example below hides the password fields in the case the User already exists:
ActiveAdmin.register User do permit_params :first_name, :last_name, :email, :password, :password_confirmationform do |f|
f.inputs "User Details" do
f.input :first_name
f.input :last_name
f.input :email
if !f.object.new_record?
f.input :password
f.input :password_confirmation
end
end
f.button :Submit
end
end
ForestAdmin
Instead, Forest relies on its powerful Layout Editor to hide or show fields. In the UI, click on the “Edit Layout” button and uncheck the fields you don’t want displayed.
About ActiveAdmin and ForestAdmin
ActiveAdmin creates a CRUD interface for each resource thanks to a programmatical approach of hybrid separate files where both the logic and the views are declared.
ForestAdmin (Litterally For-REST) relies on its Liana Gem to build a secure API which is queried by the front-end from the browser. This allows to separate the logic from the UI.
→ 👋🏻 Thanks for reading. If you liked it, please ‘clap’ several times or share it so that more people can see it, and I keep writing on similar topics.
Subscribe to get my essays here, in which I try to give a helicopter view on technology related topics.
More about me here. You can also check out some of my other top articles:
- 8 Things I learned while leaving a startup to join a big firm
- What’s Scary About AI Automation Economics
- How cryptocurrencies can finally bring value to markets
- Why no-one can prevent Elon Musk from dwarfing the airline industry
- Rails Migrations Tricks [Guide + Code] — Cheatsheet included
- The downside of “Doing things that don’t scale”