如何在表单中编辑Rails序列化哈希?

Gly*_*lds 8 activerecord ruby-on-rails ruby-on-rails-3

我在我的Rails应用程序中有一个用于公告的模型,当它被创建时,许多值作为序列化的哈希或数组存储在数据库中,以便稍后访问.我正在尝试为其中一个哈希创建一个编辑视图,但我无法弄清楚如何在我的表单中访问它.

存储时哈希看起来像这样:

top_offices = { first_office: "Office Name", first_office_amount: 1234.50, 
second_office: "Office Name", second_office_amount: 1234.50 }
Run Code Online (Sandbox Code Playgroud)

等等......有五个办公室.

所以在控制台中我可以通过执行以下操作来编辑值:

bulletin = Bulletin.last
bulletin.top_offices[:first_office] = "New Office"
bulletin.top_offices[:first_office_amount] = 1234.00
bulletin.save
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何制作一个允许我正确分配这些值的表单.我甚至不需要使用以前存储的值来填充表单,因为我在使用表单时会完全更改它们.

Zed*_*TuX 9

选项1:更新序列化属性的单实例方法

据我所知,不可能直接从表单编辑序列化属性.

当我有这种事情时,我总是在模型中创建一个接收参数并进行更新的实例方法(如果我用方法(!)结束方法名,也可以执行保存).

在你的情况下,我会做以下事情:

class Bulletin

  ...

  def update_top_offices!(params)
    params.each do |key, value|
      self.top_offices[key] = value
    end

    self.save
  end

  ...
end
Run Code Online (Sandbox Code Playgroud)

选项2:每个序列化属性键的getter/setter

如果您真的想使用表单来更新序列化属性,另一种可能性是创建一个getter/setter,如下所示:

class Bulletin

  ...

  def first_office
    self.top_offices[:first_office]
  end

  def first_office=(value)
    self.top_offices[:first_office] = value
  end

  ...
end
Run Code Online (Sandbox Code Playgroud)

但是不要忘记保存更新的值.

选项3:覆盖method_missing

最后一种可能性是覆盖,method_missing但它有点复杂.


Wiz*_*Ogz 6

这是一个示例,它只是遍历top_offices中的现有键/值对,并为它们生成表单字段.

<% @bulletin.top_offices.each do |key, value| %>
  <input name="bulletin[top_offices][<%= key %>]" type="text" value="<%= value %>" />
<% end %>
Run Code Online (Sandbox Code Playgroud)

会产生:

<input name="bulletin[top_offices][first_office]" ... />
<input name="bulletin[top_offices][first_office_amount]" ... />
# etc.
Run Code Online (Sandbox Code Playgroud)

如果您不信任您的用户,那么您可能需要对提交给top_offices的值进行完整性检查.