Create form fields for hash attribute

activerecord, ruby, ruby-on-rails, ruby-on-rails-4

Solution

The rails way needn't include the limitation of using a single table, ideally, you can do this in a very rails way with 2 tables. Moving on.

You shouldn't use Active Record `:store` for this purpose in my opinion.

That implementation is ideal for situations where the developers need to store model metadata that is flexible in-code but well-defined at any given point of time. Which is to say, you need to specify keys in the model.

There is another pit-fall, you can't run SQL queries on the resulting serialized text that is saved.

If you insist, you can do this:

In your model:

class Product < ActiveRecord::Base
  store :properties

  def prop_hash
    self.properties.collect{|k,v| [k,v]}
  end

  def prop_hash=(param_hash)
    # need to ensure deleted values from form don't persist        
    self.properties.clear 
    param_hash.each do |name, value|
      self.properties[name.to_sym] = value
    end  
  end

end

In the view:

<%= form_for @product do |f| %>
  <% f.object.prop_hash.each do |k,v| %>
    <%= text_field 'product[prop_hash][][name]', k %>
    <%= text_field 'product[prop_hash][][value]', v %>
  <% end %>
<% end %>

Then you can also add an 'add another property' link which should use JS to insert another pair of inputs with the names `product[prop_hash][][name]` and `product[prop_hash][][value]` respectively.

Long ago I had rolled a custom implementation for metadata which saves the keys in serialized XML, for one reason - it can be queried in SQL. The link to my blog article http://geniitech.tumblr.com/post/14916592782/storing-metadata-as-xml-hash-in-ror

Problem

I have a model Product, which has a properties attribute. It stores it in a single database column as a hash (following http://api.rubyonrails.org/classes/ActiveRecord/Store.html) ``` class Product < ActiveRecord::Base store :properties end ``` How can I create dynamic form fields for this property attribute (which is a hash)? I'm interested in ideologically correct way of doing this ("rails way"). I guess that there is need to use fields_for helper. But I do not fully understand how to do it. Tell me the correct way of solving this problem, please. In result, I'd like to get a working form like shown on image. Where a user can add unlimited number of fields and give any property names and its values.

Original source