使用带有序列化自定义类的Rails表单助手

IH0*_*345 6 ruby serialization activerecord ruby-on-rails ruby-on-rails-3

我正在尝试在单个数据库字段中保存选项的哈希值.表单能够将数据保存到数据库,但是当我去编辑它时无法再次检索它(例如,除了wp_options字段之外,所有其他字段都是预先填充的).

class Profile < ActiveRecord::Base  
 serialize :wp_options  
end
Run Code Online (Sandbox Code Playgroud)

这是我的自定义类:

class WP_Options
 attr_accessor :wp_name, :wp_desc, :wp_limit
end
Run Code Online (Sandbox Code Playgroud)

在我的形式:

<%= form_for(@profile, :remote => true) do |f| %>
 ...
   <%= f.fields_for :wp_options do |wp_options| %>
      <%= wp_options.text_field :wp_name  %>
   <% end %>
 ...
Run Code Online (Sandbox Code Playgroud)

在我的控制器中:

@profile = Profile.new(:wp_options => WP_Options.new)
Run Code Online (Sandbox Code Playgroud)

在我的数据库列'wp_options'中:

--- !map:ActiveSupport::HashWithIndifferentAccess 
wp_name: Test  
Run Code Online (Sandbox Code Playgroud)

任何建议都会非常感激.

Dmi*_*kin 11

实际上这很容易.您需要使用带reader方法的类.您可以使用不同的方式创建它,但最简单的方法是使用OpenStruct类(注意,它将无法查看OpenStruct实例方法中的字段...此类无法重新定义方法).

在您的表单中,您应该添加:

<%= f.fields_for :wp_options, @profile.wp_options do |wp_options| %>
Run Code Online (Sandbox Code Playgroud)

而不是@profile(如果你有动态变量),你可以使用f.object.wp_options.

对于模型,Profile您应该添加wp_options方法.

def wp_options
  OpenStruct.new(self.attributes['wp_options'])
end
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它只有在序列化的wp_options是Hash类时才有效.

希望有所帮助.

PS.我使用相同的技术,但因为我有type哈希键,OpenStruct无法创建它,所以我使用简单的Struct类.我有data专栏:

def data
  keys = current_data.keys
  data = attributes[:data]
  Struct.new(*keys).new(*keys.map { |k| data[k] })
end
Run Code Online (Sandbox Code Playgroud)

有点不那么琐碎,但无论如何都是相同的方法(在此之前我创建了特殊的类,但现在我知道Struct是创建这类东西的更好方法.你可以在这里找到更多的想法:我如何使用哈希键作为一个类的方法?)