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

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

class Company < ActiveRecord::Base serialize :names 

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

 --- short: bestbuy long: bestbuy ltd. 

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

  

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

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

但是,当我提交它时,它在数据库中成为:

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

我怎样才能使textarea显示YAML以供编辑器编辑?

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

更新

如果我像这样强制列类型为Hash

 serialize :names, Hash 

我尝试保存时会出错:

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

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

而是自己将数据转换为YAML:

 @names = m.names.to_yaml 

然后把@names塞进你的 。 然后保存已编辑的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以使其更安全。


您当前的方法是将Hash的to_s版本放入

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

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

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

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

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

 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字符串,因此用户可以对其进行编辑。

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

 names = HashWithIndifferentAccess.new({"short"=>"bestbuy", "long"=>"bestbuy ltd."}) company = Company.new company.names = names.to_yaml 

希望,这会有所帮助。