Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you handle serialized edit fields in an Active Admin resource?

I have a model, Domain, which has a text field, names.

> rails g model Domain names:text
  invoke  active_record
  create    db/migrate/20111117233221_create_domains.rb
  create    app/models/domain.rb
> rake db:migrate
==  CreateDomains: migrating ==================================================
-- create_table(:domains)
   -> 0.0015s
==  CreateDomains: migrated (0.0066s) =========================================

I set this field as serialized into an array in the model.

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

Create the ActiveAdmin resource for this model

> rails g active_admin:resource Domain
    create  app/admin/domains.rb

then, in the app/admin/domains.rb, I setup the various blocks to handle the serialized field as such

# app/admin/domains.rb
ActiveAdmin.register Domain do

  index do
    id_column
    column :names do |domain|
      "#{domain.names.join( ", " ) unless domain.names.nil?}"
    end
    default_actions
  end

  show do |domain|
    attributes_table do
      row :names do
        "#{domain.names.join( ", " ) unless domain.names.nil?}"
      end
    end
  end

  form do |f|
    f.inputs "Domain" do
      f.input :names
    end
    f.buttons
  end

  # before we save, take the param[:domain][:name] parameter,
  # split and save it to our array
  before_save do |domain|
    domain.names = params[:domain][:names].split(",") unless params[:domain].nil? or params[:domain][:names].nil?
  end
end

Nearly everything works great -- my names are displayed as comma separated in the index and show views. When I update a record with my names field set to "a,b,c", the before_save works to turn that into an array that is then saved via the ActiveRecord serialize.

What I can not solve is how to make the edit form put in a comma-separated list into the text field. I tried using a partial and using formtastic syntax directly as well as trying to make it work via the active_admin DLS syntax. Does anyone know how to make this work?

Specifically, if I have the following array saved in my domain.names field:

# array of names saved in the domain active_record
domain.names = ["a", "b", "c"]

how to change:

      form do |f|
        f.inputs "Domain" do
          f.input :names
        end
        f.buttons
      end

so that when the edit form is loaded, in the text field instead of seeing abc, you see a,b,c.

like image 420
sorens Avatar asked Nov 17 '11 23:11

sorens


1 Answers

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.buttons
end
like image 193
sorens Avatar answered Sep 29 '22 08:09

sorens