Ruby on rails 将Rails表单帮助程序与序列化的自定义类一起使用
我试图在一个DB字段中保存选项的散列。表单能够将数据保存到数据库中,但在我去编辑它时无法再次检索它(例如,除wp_选项字段外,所有其他字段都已预填充) 以我的名义:Ruby on rails 将Rails表单帮助程序与序列化的自定义类一起使用,ruby-on-rails,ruby,serialization,activerecord,ruby-on-rails-3,Ruby On Rails,Ruby,Serialization,Activerecord,Ruby On Rails 3,我试图在一个DB字段中保存选项的散列。表单能够将数据保存到数据库中,但在我去编辑它时无法再次检索它(例如,除wp_选项字段外,所有其他字段都已预填充) 以我的名义: <%= form_for(@profile, :remote => true) do |f| %> ... <%= f.fields_for :wp_options do |wp_options| %> <%= wp_options.text_field :wp_name %
<%= form_for(@profile, :remote => true) do |f| %>
...
<%= f.fields_for :wp_options do |wp_options| %>
<%= wp_options.text_field :wp_name %>
<% end %>
...
在我的数据库列“wp_选项”中:
--- !map:ActiveSupport::HashWithIndifferentAccess
wp_name: Test
任何建议都将不胜感激。事实上这很容易。您需要将类与
reader
方法一起使用。您可以使用不同的方法创建它,但最简单的方法是使用OpenStruct
类(注意,它将无法看到OpenStruct实例方法中的字段……此类无法重新定义方法)
在表格中,您应添加:
<%= f.fields_for :wp_options, @profile.wp_options do |wp_options| %>
在这种情况下,只有当序列化的wp_选项是散列类时,它才会起作用
希望有帮助
另外,我使用了同样的技术,但因为我有type
hash键,OpenStruct无法创建它,所以我使用了简单的Struct类。我有数据
栏:
def data
keys = current_data.keys
data = attributes[:data]
Struct.new(*keys).new(*keys.map { |k| data[k] })
end
稍微不那么琐碎,但无论如何都是相同的方法(在此之前我创建了特殊类,但现在我知道Struct是创建此类内容的更好方法。您可以在这里找到更多想法:)对于使用Dmitry解决方案的用户,在rails 3.0.5上(不确定上一个/下一个版本,所以请尝试之前),添加 添加到environment.rb文件,以便包含OpenStruct 如果要使用JSON进行序列化,请在您的模型中添加(哦,我对RoR很陌生,所以请仔细研究并提出一个比这个更好的“有效”解决方案)(我的变量名更改为与上述示例匹配):
最后一点:老实说,我不知道为什么它必须存储在self.wp_选项中,而不是self.attributes['wp_选项'],如果有人能解释的话,那会很酷。我遇到了同样的问题。我的解决办法如下:
def wp_options_text_field(profile, wp_options, name)
wp_options.text_field name, :value => profile.wp_options[name]
end
<%= form_for(@profile, :remote => true) do |f| %>
...
<%= f.fields_for :wp_options do |wp_options| %>
<%= wp_options_text_field :wp_name %>
<% end %>
...
true)do | f |%>
...
...
这里唯一的问题是,您需要为要使用的每个助手方法定义方法。在我的例子中,我只使用了两种方法,这并不痛苦。我需要我的wp_选项作为散列保留,这样我就可以迭代它的条目。因此,我没有对模型做任何更改,而是将
OpenStruct.new
以这样的形式放置:也许它的视图可以窥视模型实现,但它所知道的是wp_选项是一个散列,而不是一个带有attr方法的对象。
def wp_options
OpenStruct.new(self.attributes['wp_options'])
end
def data
keys = current_data.keys
data = attributes[:data]
Struct.new(*keys).new(*keys.map { |k| data[k] })
end
require 'ostruct'
before_save :json_serialize
after_save :json_deserialize
after_find :json_deserialize
def json_serialize
self.wp_options = ActiveSupport::JSON.encode(self.attributes['wp_options'])
end
def json_deserialize
unless (self.attributes['wp_options'].nil?)
self.wp_options = ActiveSupport::JSON.decode(self.attributes['wp_options'].to_s)
end
end
def wp_options_text_field(profile, wp_options, name)
wp_options.text_field name, :value => profile.wp_options[name]
end
<%= form_for(@profile, :remote => true) do |f| %>
...
<%= f.fields_for :wp_options do |wp_options| %>
<%= wp_options_text_field :wp_name %>
<% end %>
...