HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyrailsMinor

ActiveAdmin: Hide a whole panel in a smart way

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
activeadminwholewaypanelsmarthide

Problem

In order to only show relevant information to my users I want to disable the whole panel when all fields inside that panel are empty.

Currently I do this hacky method to get to this result:

if resource.phone.present? or
    resource.fax.present? or 
    resource.email.present? or 
    resource.website.present?
  panel I18n.t('contact_details') do
    attributes_table_for resource do
      row :phone if resource.phone.present?
      row :fax if resource.fax.present?
      row :email if resource.email.present?
      row :website if resource.website.present?
    end
  end
end


So I need to check all fields in order to know if I display the panel.
Then once I display the panel I need to check all the fields again in order to display the given row or not.

Now the user sees only what is relevant but my admin code is cluttered and no longer as maintainable.

Solution

I don't know ActiveAdmin, so I can only offer a local improvement. That said, a little metaprogramming could work here. The idea is to have the list of resource items in one place:

RESOURCES_ITEMS = [
  :phone,
  :fax,  
  :email,   
  :resource,
]


and then use that list with Object#public_send and Enumerable#any?:

if RESOURCE_ITEMS.any? { |item| resource.public_send(item).present? }
  panel I18n.t('contact_details') do
    attributes_table_for resource do
      RESOURCE_ITEMS.each do |item|
        if resource.public_send(item).present?
          row.public_send(item)
        end
      end
    end
  end
end


While not a huge improvement, this does DRY the list of resource items.

Code Snippets

RESOURCES_ITEMS = [
  :phone,
  :fax,  
  :email,   
  :resource,
]
if RESOURCE_ITEMS.any? { |item| resource.public_send(item).present? }
  panel I18n.t('contact_details') do
    attributes_table_for resource do
      RESOURCE_ITEMS.each do |item|
        if resource.public_send(item).present?
          row.public_send(item)
        end
      end
    end
  end
end

Context

StackExchange Code Review Q#140838, answer score: 3

Revisions (0)

No revisions yet.