Rails4 fields_for和序列化哈希。得到'TypeError:expect Hash(got String)'

时间:2013-09-27 12:44:54

标签: ruby-on-rails ruby serialization hash ruby-on-rails-4

我已经序列化了Product

的属性属性
class Product < ActiveRecord::Base
  serialize :properties, Hash

产品表(sqlite3)的文本列'properties'包含如下内容:

---
:article: shirt
:size: L
:color: red

当我从控制台检索产品的属性时,我获得了一个哈希,我可以修改并保存,没有任何问题。 Ruby完美地序列化和反序列化它。 然后我尝试使用fields_for:

为每个属性构建一个带有text_field的_form.html.erb
<%= form_for(@product) do |f| %>
[....]
  <div class="field">
    <%= f.fields_for :properties, OpenStruct.new(@product.properties) do |property_form| %>
      <%= f.label :properties %><br />
      <% @product.properties.keys.each do |k| %>
        <%= property_form.label k %><br />
        <%= property_form.text_field k, :value => @product.properties[k] %>
      <% end %>
    <% end %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

当我编辑产品时,此代码会创建3个填充了正确值的text_fields,但是当我尝试保存它时,我得到:

  

“错误TypeError:param'属性'的预期Hash(得到字符串)”

怎么了?我已经通过一些解决方案阅读了很多类似的问题,我遵循thisRailscast#403中建议的不同方法,但我总是遇到这种错误。我可能错过了什么,但我找不到什么。任何的想法? (ruby-2.0.0-p247,Rails 4.0.0)

非常感谢!

1 个答案:

答案 0 :(得分:0)

由于我遇到困难并需要快速解决方案,我使用了一个简单的解决方法:我为每个text_field创建了一个变量'property_n',并在保存对象之前将其复制到哈希中。 现在编辑表单是这样的:

<% for i in 0..max_num_of_properties %>
  <div class="field">
    <%= f.label "property_#{i}".to_sym %><br>
    <%= f.text_field "property_#{i}".to_sym %>
  </div>
<% end %>

和产品类是:

class Product < ActiveRecord::Base
  serialize :properties, Hash

  before_save do
    self.properties = {}
    property_names = ProductType.find(product_type_id).get_property_names()
    property_names.each_with_index do |name, index|
      self.properties[name] = get_property(index)
    end
  end

  def get_property(index)
    send("property_#{index}")
  end
哈希现在顺利完成序列化。使用JS的一些行我在编辑表单中显示正确的数字和属性名称(来自ProductType)。 我知道这不是完美的解决方案,但它可能对某人有用......