我有以下内容。
class Page < ActiveRecord::Base
belongs_to :category
serialize :fields
end
fields
的值取决于类别。但作为一个例子;
{"address" => "8 finance street, hong kong",
"founded" => "1973"}
在此示例中,类别已将"address"
和"founded"
定义为自定义字段。
我想要的是说;
= simple_form_for(@page) do |f|
= f.association :category
- f.object.category.fields.each do |field|
= f.input field.name
但我需要做一些神奇的事情来处理@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]
现在需要制作这个DRYer(不想指定对象的名称)。
我会看看我是否可以为此编写一个像样的简单表单扩展名。
答案 0 :(得分:25)
我遇到了类似的问题,试图在Mongoid模型的Hash字段类型上使用simple_fields_for
。我正在处理的示例的Mongoid版本看起来像这样:
class Page
include Mongoid::Document
field :fields, type: Hash
end
我的情况可能略有不同,因为我已经知道我提前查找的哈希键,只需要simple_fields_for
来处理哈希字段。我使用的天真方法(基本fields_for
用法)看起来像这样:
= simple_form_for(@page) do |f|
= f.simple_fields_for :fields do |ff|
= ff.input :address
= ff.input :founded
但这并没有正确填写表格。 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
为了避免将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
现在我可以使用原始的天真解决方案而无需特殊的视图代码。
答案 1 :(得分:3)
使用OpenStruct。它的工作原理如下:
require 'ostruct'
struct = OStruct.new("address" => "8 finance street, hong kong", "founded" => "1973")
struct.address # => 8
struct.founded # => "1973"
答案 2 :(得分:1)
答案 3 :(得分:1)
如果我之前只发现这篇文章,我就不会错过这个问题的三天。
我无法对answear发表评论,只是为了补充一下,如果有人试图fields_for
mongo哈希数组(has_many like),你还需要提供一个{{1}的根OpenStruct对象}}(在本例中为fields_attributes =)方法,因此"#{key}_attributes="
会识别它是一个has_many关系。
希望它可以帮到某人;)