I found myself dealing a lot with ActiveAdmin recently. While editing entries there is often the requirement to add/edit multiple associated entries. A simple example would be a customer site with its associated contacts. Here are both models Site and Contact:

Class Site < ActiveRecord::Base
  has_many :contacts

  attr_accessible :name
end

Class Contact < ActiveRecord::Base
  belongs_to :site

  attr_accessible :firstname, :lastname, :phone, :email, :site_id
end

After several attempts to implement it on different parts of the system - here are the exact steps you need to take in order to make it work.

  1. Allow nested attributes for Contacts on Site
  2. Add permit params statement for ActiveAdmin’s Site
  3. Add needed form elements

Nested attributes

When you submit the form later, it will have data to set the new contact/contacts. In order to process them you need to allow the processing explicitly by adding the following to site.rb:

  accepts_nested_attributes_for :contacts, allow_destroy: true

Permit params

The documentation for ActiveAdmin states:

Use the permit_params method to define which attributes may be changed… Any form field that sends multiple values (such as a HABTM association, or an array attribute) needs to pass an empty array to permit_params… Nested associations in the same form also require an array, but it needs to be filled with any attributes used.

Here we are dealing with nested associations, thus the need to add the following:

  permit_params :name, contacts_attributes: [ :id, :firstname, :lastname, :phone, :email, :_destroy, :_create, :_update ]

The name attribute belongs to the Site model itself. Then contacts_attributes get defined in an array. Permitted methods are also defined with an underscore.

Add form elements

The last step is to add the form elements to the ActiveAdmin Site:

form do |f|
  f.inputs 'Details' do
   f.input :name
  end

  f.inputs 'Contacts' do
    f.has_many :contacts do |c|
      c.input :firstname
      c.input :lastname
      c.input :phone
      c.input :email
    end
  end

  f.actions
end

The end result

Here is the end result with the Rails models and ActiveAdmin site. Since I wrote down the three steps for my self the need to google and debug this feature completely disappeared for me.

Site and Contact models

Class Site < ActiveRecord::Base
  has_many :contacts

  attr_accessible :name, :contacts_attributes
  accepts_nested_attributes_for :contacts, allow_destroy: true
end

Class Contact < ActiveRecord::Base
  belongs_to :site

  attr_accessible :firstname, :lastname, :phone, :email, :site_id
end

ActiveAdmin form

ActiveAdmin.register Site do
  permit_params :name, contacts_attributes: [ :id, :firstname, :lastname, :phone, :email, :_destroy, :_create, :_update ]

  # Show
  show do
    attributes_table do
     row  :name
    end

    panel 'Concacts' do
      table_for site.contacts do
        column :firstname
        column :lastname
        column :phone
        column :email
      end
    end
  end

  # Edit
  form do |f|
    f.inputs 'Details' do
     f.input :name
    end

    f.inputs 'Contacts' do
      f.has_many :contacts do |c|
        c.input :firstname
        c.input :lastname
        c.input :phone
        c.input :email
      end
    end

    f.actions
  end
end