Как вы обрабатываете сериализованные поля редактирования в ресурсе Active Admin?

У меня есть модель, Domain, которая имеет текстовое поле, 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) =========================================

Я установил это поле как serialized в массив в модели.

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

Создайте ресурс ActiveAdmin для этой модели

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

то в app/admin/domains.rb я настраиваю различные блоки для обработки сериализованного поля как такового

# 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

Почти все отлично работает - мои имена отображаются как запятые, разделенные в индексе и отображающие представления. Когда я обновляю запись с моим полем имен, установленным на "a, b, c", before_save работает, чтобы превратить это в массив, который затем сохраняется через сериализацию ActiveRecord.

Я не могу решить, как сделать форму редактирования помещенной в разделенный запятыми список в текстовое поле. Я попытался использовать частичный и использовать formtastic синтаксис напрямую, а также попытаться заставить его работать через синтаксис Active_admin DLS. Кто-нибудь знает, как сделать эту работу?

В частности, если у меня есть следующий массив, сохраненный в поле domain.names:

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

как изменить:

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

, чтобы при загрузке формы edit в текстовом поле вместо abc вы видите a,b,c.

Ответ 1

Вот краткое описание того, как я справлялся с этой ситуацией. Я добавил аксессуар к модели, которая может превратить 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

то в моем ресурсе admin для домена вместо использования поля :names я использовал поле :names_raw. это значение сохранит имена Array с новыми значениями.

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

Ответ 2

Наткнулся на этот вопрос, ища что-то, чтобы получить доступ к сериализованному Hash YAML. Я использовал это решение на Rails 3.2:

def target_raw
  @attributes['target'].serialized_value
end

def target_raw=(new_value)
  @attributes['target'].state = :serialized
  @attributes['target'].value = new_value
end