Mohd Anas
Mohd Anas

Reputation: 644

How to save array in Active Admin Rails 4?

I am using Active Admin in Rails 4. In my model i have one field which is an Postgres array type when i am creating the object it is passing in background but it is not saving to the database. So what i need to do to save the array field in database through Active Admin.

Thanks

Upvotes: 15

Views: 10221

Answers (5)

Aaron Rory
Aaron Rory

Reputation: 26

Here's what my solution looks like:

My Migration:

  def change
    add_column :agency_services, :required_fields, :string, array: true, default: []
  end

Active Admin Resource Model:

  permit_params [required_fields: []]

  controller do
    def update
      params[:agency_service][:required_fields] = params[:agency_service][:required_fields].split(' ')
      super
    end
  end

And how I format each individual item meant to be set as an array:

occupation home_number work_number

afterwards this ends up translating into this:

[occupation, home_number, work_number]

Since I set the String.split(' ') function to a blank space, it separates the items to be arrayed by spaces but you can use a comma too...

Upvotes: 0

Vedant Agarwala
Vedant Agarwala

Reputation: 18819

You have hack stuff since active admin doesn't support it out of the box, it seems.

Though this answer is old, it works: How do you handle serialized edit fields in an Active Admin resource?

Here is a summary of how I handled this situation. I added an accessor to the model which can turn the Array into a string joined by a linefeed and split it back to an Array.

# app/models/domain.rb
class Domain < ActiveRecord::Base
  serialize       :names, Array
  attr_accessor   :names_raw

  def names_raw
    self.names.join("\n") unless self.names.nil?
  end

  def names_raw=(values)
    self.names = []
    self.names=values.split("\n")
  end
end

then, in my admin resource for domain, instead of using the :names field, I used the :names_raw field. setting this value would save the names Array with the new values.

# app/admin/domains.rb
form do |f|
  f.inputs "Domain" do
    f.input :names_raw, :as => :text
  end
  f.actions
end

Upvotes: 17

ShilpeshAgre
ShilpeshAgre

Reputation: 291

The simple solution which can be used, if you not need some fancy form for editing

Write a Setter method module which can be used on any model

module StringToArrayValueSetter
  def string_to_array_setter(*column_names)
    column_names.each do |column_name|
      define_method("#{column_name}=") do |val|
        value = val.is_a?(String) ? YAML.load(val) : val 
        super value
      end
    end
  end
end

Extend the setter method to your model

class Thing < ApplicationRecord
   extend StringToArrayValueSetter
   string_to_array_setter :column1, :column2
end

make your array column default to [], it will be always filled by an empty array

Upvotes: 0

adesurirey
adesurirey

Reputation: 2620

Simple hack I found :

As Postgres treats arrays as text you can keep the default input for it and just parse the params as if it was some json.

# app/admin/model.rb

controller do
  def update
    params[:model][:array_attribute] = JSON.parse params[:model][:array_attribute]
    super
  end
end

Tips: make your array attribute default to [] so your input will already be filled with an empty array. You can also customize your input as if it was json for a better edtiting experience see https://github.com/udacity/activeadmin_json_editor

Upvotes: 0

Jordan Sitkin
Jordan Sitkin

Reputation: 2343

Here's a similar but even simpler take on a solution if you don't need a fancy UI for the admin.

# app/model/thing.rb
def some_array_column= items
  if items.is_a? String
    super items.split(" ")
  else
    super items
  end
end

And

# app/admin/thing.rb
ActiveAdmin.register Thing do
  index do
    column "Things" { |t| (t.some_array_column || []).join(" ") }
  end
end

Upvotes: 5

Related Questions