Has many associations in ActiveAdmin
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.
- Allow nested attributes for Contacts on Site
- Add permit params statement for ActiveAdmin’s Site
- 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