序列化哈希字段和简单表单

Mat*_*udy 11 serialization ruby-on-rails ruby-on-rails-3 simple-form

我有以下内容.

class Page < ActiveRecord::Base
  belongs_to :category
  serialize :fields
end
Run Code Online (Sandbox Code Playgroud)

价值fields将取决于类别.但作为一个例子;

{"address" => "8 finance street, hong kong",
 "founded" => "1973"}
Run Code Online (Sandbox Code Playgroud)

在此示例中,类别已定义"address""founded"作为自定义字段.

我想要的是说;

= simple_form_for(@page) do |f|
  = f.association :category
  - f.object.category.fields.each do |field|
    = f.input field.name
Run Code Online (Sandbox Code Playgroud)

但我需要做一些神奇的事情来处理@page.founded无效的事实

相反,我应该看看@page.fields["founded"].

有什么建议?


更新:

我有点接近了

- if f.object.category
  - f.object.category.fields.each do |field|
    = f.input field.name do
      = text_field_tag "post[fields][#{field.name}]", f.object.fields[file.name]
Run Code Online (Sandbox Code Playgroud)

现在需要制作这个DRYer(不想指定对象的名称).

我会看看我是否可以为此编写一个像样的简单表单扩展.

Abe*_*ker 25

我遇到了一个类似的问题,试图simple_fields_for在一个Mongoid模型的Hash字段类型上使用.我正在处理的示例的Mongoid版本看起来像这样:

class Page
  include Mongoid::Document
  field :fields, type: Hash
end
Run Code Online (Sandbox Code Playgroud)

我的情况可能略有不同,因为我已经知道我提前查找的哈希键,只需要simple_fields_for使用哈希字段.fields_for我使用的天真方法(基本用法)看起来像这样:

= simple_form_for(@page) do |f|
  = f.simple_fields_for :fields do |ff|
    = ff.input :address
    = ff.input :founded
Run Code Online (Sandbox Code Playgroud)

但这并没有正确填写表格.nicholaides在一个结构中包装哈希的解决方案对我有用:

- require 'ostruct'
= simple_form_for(@page) do |f|
  = f.simple_fields_for :fields, OpenStruct.new(@page.fields) do |ff|
    = ff.input :address
    = ff.input :founded
Run Code Online (Sandbox Code Playgroud)

为了避免将OpenStruct内容混合到我的视图中,我创建了一个猴子补丁,用于simple_form在OpenStruct中自动包装哈希类型并将其放入初始化程序中:

require 'ostruct'

module SimpleForm::ActionViewExtensions::Builder
  def simple_fields_for_with_hash_support(*args, &block)
    if args[0] && !args[1]
      field = object.send(args[0])
      args << OpenStruct.new(field) if field.respond_to?(:has_key?)
    end
    simple_fields_for_without_hash_support(*args, &block)
  end
  alias simple_fields_for_without_hash_support simple_fields_for
  alias simple_fields_for simple_fields_for_with_hash_support
end
Run Code Online (Sandbox Code Playgroud)

而现在我可以使用我原来天真的解决方案而无需特殊的视图代码.