Rails | ActiveAdmin |Custom checkboxes collection for array field

Sometimes you might want to store coherent information in single string field in database. For such fields you might want the Admin to have some mechanism to update.

In Rails you can have Array field like

# in migration file
# Array Types
t.string :open_days,       array: true, default: []
t.string :payment_options, array: true, default: []
t.text   :vehicle_vendors, array: true, default: []
t.text   :services_ids,    array: true, default: []

for such fields the form builder would look like

# I am using Formtastic syntax
f.input :payment_options, as: :check_boxes, collection: PaymentOption.all.map{|x| [x.name, x.id]}

# this will yield form like
<ol class="choices-group">
<li class="choice"><label for="garage_payment_options_1"><input type="checkbox" name="garage[payment_options][]" id="garage_payment_options_1" value="1">Master Card</label></li>
<li class="choice"><label for="garage_payment_options_2"><input type="checkbox" name="garage[payment_options][]" id="garage_payment_options_2" value="2">Visa</label></li>
<li class="choice"><label for="garage_payment_options_3"><input type="checkbox" name="garage[payment_options][]" id="garage_payment_options_3" value="3">American Express</label></li>
<li class="choice"><label for="garage_payment_options_4"><input type="checkbox" name="garage[payment_options][]" id="garage_payment_options_4" value="4">Diners Club</label></li>
<li class="choice"><label for="garage_payment_options_5"><input type="checkbox" name="garage[payment_options][]" id="garage_payment_options_5" value="5">Debit Card</label></li>
<li class="choice"><label for="garage_payment_options_6"><input type="checkbox" name="garage[payment_options][]" id="garage_payment_options_6" value="6">Fall</label></li>
<li class="choice"><label for="garage_payment_options_7"><input type="checkbox" name="garage[payment_options][]" id="garage_payment_options_7" value="7">Financing and Installments</label></li>
<li class="choice"><label for="garage_payment_options_8"><input type="checkbox" name="garage[payment_options][]" id="garage_payment_options_8" value="8">Paypal</label></li>
</ol>

When such data is submitted you can pry into it and find

pry(#<Admins::GaragesController>)> params[:garage][:payment_options]
=> ["", "2", "3", "4", "6"]

Now, the problem is, you have successfully gathered data from the admin; it will save the data if permitted properly but how would the form retain the already saved value?

ActiveAdmin.register Garage do
  permit_params :name, :some_column_name, {payment_options: []}
  # the empty array indicates that this attribute is gonna save an array data.

Now, to retain the selected value in the reloaded-form, try this

collected_data = PaymentOption.all.map{|x| [x.name, x.id, {checked: f.object.payment_options.include?(x.id.to_s)}]}
f.input :payment_options, as: :check_boxes, collection: collected_data

the checked: [boolean] determines whether to check the box while rendering.

Helpful Links

http://stackoverflow.com/a/39329678/3437900

http://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s