I'm trying to save a hash of options in a single DB field. The form is able to save the data to the DB but not able to retrieve it again when I go to edit it (e.g. all the other fields are prepopulated except for the wp_options fields).
class Profile < ActiveRecord::Base
serialize :wp_options
end
This is my custom class:
class WP_Options
attr_accessor :wp_name, :wp_desc, :wp_limit
end
In my form:
<%= form_for(@profile, :remote => true) do |f| %>
...
<%= f.fields_for :wp_options do |wp_options| %>
<%= wp_options.text_field :wp_name %>
<% end %>
...
In my controller:
@profile = Profile.new(:wp_options => WP_Options.new)
In my DB column 'wp_options':
--- !map:ActiveSupport::HashWithIndifferentAccess
wp_name: Test
Any advice would be really appreciated.
Actually it's easy. You need to use class with
reader
methods. You can create it with a different ways, but the easiest one is to useOpenStruct
class (notice, that it will be unable to see fields that are in the OpenStruct's instance methods... this class cannot redefine methods).In your form you should add:
Instead of @profile (if you have dynamic variable) you can use
f.object.wp_options
.And to the model
Profile
you should addwp_options
method.In that case it will only work if your serialized wp_options is a Hash class.
Hope that helps.
PS. I used same technique, but because I had
type
hash keys, OpenStruct were unable to create it, so I used simple Struct class. I haddata
column:A little less trivial, but anyway the same approach (before that I've created special class, but now I know that Struct is the better way to creating of that kind stuff. More ideas you can find here: How do I use hash keys as methods on a class?)
I encountered the same problem. My solution was the following:
Define a method in your helper:
In your view:
The only problem here is that you'll need to define methods for each helper method you'll use. In my case I had only 2 methods used and it wasn't painful.
For those using Dmitry's solution, on rails 3.0.5 (not sure about prev/next versions so try before), add
to your environment.rb file in order to have OpenStruct included.
If you're going to serialize with JSON, in your model add (oh and I'm quite new to RoR, so please feel free to scrutinize and suggest a better, "working" solution then this one) (my variable names changed to match the above example):
On a final note: I'm honestly not sure why it has to be stored into self.wp_options and not self.attributes['wp_options'], if someone could explain it would be cool.