如何在 Active Admin Rails 4 中保存数组?

14

我正在Rails 4中使用Active Admin。在我的模型中,我有一个字段,它是Postgres数组类型。当我创建对象时,它会在后台传递,但并没有保存到数据库中。所以我需要做些什么通过Active Admin将数组字段保存到数据库中。

谢谢


数组类型?您正在使用哪个数据库服务器? - phoet
是的,Postgres服务器9.1 - Mohd Anas
请问,您是否仔细阅读了我的问题?我正在尝试通过Active Admin进行保存。 - Mohd Anas
啊啊啊,不对啊。但是无论如何,一些搜索结果显示目前似乎不支持此功能:https://github.com/gregbell/active_admin/issues/2064 - phoet
5个回答

17

看起来你必须进行黑客攻击,因为active admin没有直接支持它。

虽然这个答案有些老,但是它还能用:如何处理Active Admin资源中的序列化编辑字段?

以下是我处理此情况的摘要。我向模型添加了一个存取器,可以将数组转换为由换行符连接的字符串,并将其拆分回数组。

# 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
然后,在我的域管理资源中,我使用了:names_raw字段代替:names字段。设置该值将保存具有新值的名称数组。
# app/admin/domains.rb
form do |f|
  f.inputs "Domain" do
    f.input :names_raw, :as => :text
  end
  f.actions
end

1
【新版本】更新一下,来帮助那些使用激活记录(Active Records)>=4.1以及本地数组字段(即支持数组列的数据库)的同行们。不要使用序列化(serialize)。参考 https://github.com/rails/rails/issues/29498 - imsinu9

5

如果您不需要一个复杂的管理员用户界面,这是一个类似但更简单的解决方案。

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

并且

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

0

我发现了一个简单的技巧:

由于Postgres将数组视为text,因此您可以保留其默认输入,并将参数解析为某种json

# app/admin/model.rb

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

提示:将您的数组属性默认设置为[],这样您的输入将已经填充了一个空数组。您还可以自定义您的输入,就像它是JSON一样,以获得更好的编辑体验,请参见https://github.com/udacity/activeadmin_json_editor


0
这是我的解决方案的样子: 我的迁移:
  def change
    add_column :agency_services, :required_fields, :string, array: true, default: []
  end

Active Admin 资源模型:

  permit_params [required_fields: []]

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

如何格式化每个要设置为数组的单独项:

职业 家庭电话 工作电话

之后,它会被转换成这样:

[职业,家庭电话,工作电话]

由于我将String.split(' ')函数设置为空格,因此它通过空格将要组成数组的项分开,但您也可以使用逗号...


0

如果您不需要一些花哨的表单进行编辑,可以使用简单的解决方案

编写一个Setter方法模块,可用于任何模型

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

将setter方法扩展到您的模型中

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

将你的数组列设为默认值[],它将始终填充一个空数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接