如何为json嵌套哈希自定义simple_form

时间:2013-08-10 15:47:06

标签: ruby-on-rails simple-form

我有一些嵌套数据:

@preset = Preset.new
#fields is a postgres json data type
@preset.fields =  {'primary_category' => {'category_id' => 57882}}

我希望在表单提交的POST params[:preset][:fields]中保留相同的嵌套结构,所以我的形式为部分:

<%= text_field_tag("preset[fields][primary_category][category_id]",nil) -%>

简单表单不知道如何处理postgres新类型,如hstore或json类型。在我的情况下,我真的不需要它来验证或检测数据类型。有没有办法可以扩展SimpleForm来跳过对列类型的检测,只输出它为textfields输出的相同的现有bootstrap样板,但对于我的任意json嵌套键?

也许是这样的用法:

<%= f.input 'preset[fields][primary_category][category_id]', :as => :json_text_field %>

输出与上面的帮助相同的东西,但是用标签和控制组分类的div等包围。

我已经考虑过根据文档扩展输入基类。

class JsonTextFieldInput < SimpleForm::Inputs::Base
  def input
    "#{@builder.text_field(???, input_html_options)}".html_safe
  end
end

但是这里是我迷路的地方,因为我不知道要传递给@builder以绕过用我自己的逻辑来检查属性名称来映射它的哈希键。此外,只更改表单输入而不是标签,这也需要进行一些修改。在任何一种情况下,我都无法走得太远,我可以使用一些指导。

1 个答案:

答案 0 :(得分:4)

我正在将它用于jsonb / json输入:

class JsonbInput < SimpleForm::Inputs::StringInput
  def input()
    out = ActiveSupport::SafeBuffer.new
    Hash[object.send(attribute_name).sort].each do | k, v|
      out << template.content_tag(:div, class: 'group') do
        template.concat @builder.label(k, object.send(attribute_name), label_html_options)
        template.concat @builder.text_field(k, input_html_options)
      end
    end
    out
  end

  def input_html_options
    {class: 'string form-control'}
  end

end

您还需要在模型中使用store_accessor。