【问题标题】:Edit a serialized hash in a form?编辑表单中的序列化哈希?
【发布时间】:2011-06-30 19:22:34
【问题描述】:

我正在序列化存储在表中 settings 字段中的哈希,并且希望能够在表单字段中编辑该哈希。

class Template < ActiveRecord::Base
  serialize :settings
end

但我只是做&lt;%= f.text_area :settings %&gt; 然后文本区域只显示序列化数据而不是哈希。

如何让哈希显示在文本区域中?

【问题讨论】:

  • 您希望在 textarea 中看到什么?像{:foo=&gt;'bar'} 这样的东西?一个问题是,当您提交表单时,设置字段将被序列化为字符串,而不是哈希,除非您向应用程序添加一些逻辑。逻辑最好放在模型中。
  • 正确。我想看看{:foo=&gt;'bar'}

标签: ruby-on-rails serialization hash


【解决方案1】:

也许为您的模型设置另一个访问器会起作用。

class Template < ActiveRecord::Base
  serialize :settings
  attr_accessor :settings_edit

  before_save :handle_settings_edit, :if => lambda {|template| template.settings_edit.present? }

  def settings_edit
    read_attribute(:settings).inspect   # should display your hash like you want
  end

  protected
    def handle_settings_edit
      # You may want to perform eval in your validations instead of in a 
      # before_save callback, so that you can show errors on your form.
      begin
        self.settings = eval(settings_edit)
      rescue SyntaxError => e
        self.settings = settings_edit
      end
    end  
end

然后在您的表单中使用&lt;%= f.text_area :settings_edit %&gt;

我没有测试过这些代码,但理论上它应该可以工作。祝你好运!

警告:像这样使用eval 是非常危险的,在此示例中,用户可以删除整个模板表,只需在编辑框Template.destroy_all 中添加一行即可。如果涉及用户输入,请使用其他方法将字符串转换为哈希。

【讨论】:

  • 实际上...这似乎不起作用。当我编辑表单并提交(更新)时,它不会将更改保存到settings...它保留以前的数据。
  • 有什么变化吗?你在用attr_accessible吗?如果是这样,请确保您允许批量分配给settings_edit
  • 没有改变,我没有使用attr_accessible
  • 这很接近。问题是语句“eval(settings_edit)”正在读取您在上面定义的方法。我通过删除方法 def settings_edit 并在控制器中的编辑操作中添加“@template.settings_edit = @template.read_attribute(:settings).inspect”行来实现此功能。
  • 在用户输入中使用eval 是不安全的。恶意用户可以将任何 Ruby 代码粘贴在表单字段中并在您的服务器上执行。
【解决方案2】:

...或者你可以使用这样的东西(模型中没有任何逻辑):

<% @template.settings.each do |name, value| %>
  <div>
    <%= label_tag name %>
    <%= text_field_tag "template[settings][#{name}]", value %>
  </div>
<% end %>

【讨论】:

  • 是的,这可行,但您需要在表单中添加更多逻辑才能将新的键/值对添加到设置哈希中。
  • 是的,实际上它会非常复杂 :) 所以如果你有预定义的配置键并且不希望添加或删除键,这种方法可以工作
【解决方案3】:

你应该使用类似的东西

class Template < ActiveRecord::Base
  serialize :settings, Hash
end

【讨论】:

  • 不改变 text_area 的内容
猜你喜欢
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
  • 2013-04-17
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 2022-01-05
  • 2015-03-12
相关资源
最近更新 更多