如何在textarea格式中编辑序列化哈希列

时间:2012-04-27 05:10:09

标签: ruby-on-rails ruby-on-rails-3 serialization

我在公司模型中有一个序列化列:

class Company < ActiveRecord::Base
  serialize :names

理想情况下,我希望它在数据库中存储不同的名称:

---
short: bestbuy
long: bestbuy ltd.

目前在我的公司#edit页面中,我有一个文本区域:

<%= f.text_area :names %>

如果我在数据库中有该YAML,它将在浏览器中显示为:

{"short"=>"bestbuy", "long"=>"bestbuy ltd."}

然而,当我提交它时,它在数据库中变成了:

--- ! '{"short"=>"bestbuy", "long"=>"bestbuy ltd."}'

问题

我如何才能使textarea显示YAML以便编辑进行编辑?

如何让数据库保存正确的YAML,而不是YAML和ruby哈希的混搭?

更新

如果我强制列为Hash类型,请执行以下操作:

serialize :names, Hash

我尝试保存时会出错:

Admin中的

ActiveRecord :: SerializationTypeMismatch#CompaniesController#update
属性应该是一个哈希,但是一个字符串

3 个答案:

答案 0 :(得分:4)

您可以使用原始SQL手动删除数据库,但如果您还不知道自己在做什么,我不会推荐它。一个必然结果是你不应该乱用数据库的YAML版本,除非你已经确切地知道你正在做什么。

相反,请自行将数据转换为YAML:

@names = m.names.to_yaml

然后将@names填入您的<textarea>。然后保存已编辑的YAML,将其解析回Hash并将其移交给您的模型:

m.names = YAML.parse(params[:names])

# Or modify `params` in-place
params[:name] = YAML.load(params[:names])
# then stuff `params` into `m` as usual

为了安全起见,您应该指定您的names应该是模型中的哈希:

serialize :names, Hash

我不是serialize的忠实粉丝所以我通常建议不要使用它;但是,如果您打算使用它,则应始终指定class_name以使其更安全。


您当前的方法是将to_s版本的哈希值放入<textarea>

{"short"=>"bestbuy", "long"=>"bestbuy ltd."}

这是一个字符串,而不是哈希;它可能看起来像一个哈希,但HTML不知道Ruby Hash是什么,所以它只是一个字符串。然后你读回来并把它放进names然后YAMLifies(作为一个字符串)到这个:

--- ! '{"short"=>"bestbuy", "long"=>"bestbuy ltd."}'

这是YAML中的一个字符串,这个字符串看起来很像哈希,但仍然是一个字符串。

答案 1 :(得分:0)

对我自己的问题的回答很晚:

class ConfigSerializer
  def self.load(i)
    if i.blank?
      {}
    else
      YAML.load(i)
    end
  end

  def self.dump(i)
    i = {} if i.blank?

    if i.is_a?(String) # Allow assigning an YAML string as input 
      i
    else
      YAML.dump(i)
    end
  end
end

并在模型中

serialize :names, ConfigSerializer

这样我可以分配一个YAML字符串,它将按原样存储到数据库中。只有从数据库加载它才会转换为哈希对象。

在视图中我将textarea设置为具有原始YAML字符串,因此用户可以对其进行编辑。

答案 2 :(得分:-2)

尝试将名称存储到db中,如:

names = HashWithIndifferentAccess.new({"short"=>"bestbuy", "long"=>"bestbuy ltd."})
company = Company.new
company.names = names.to_yaml
希望,这会有所帮助。

相关问题