我在Rails 3应用程序中保存散列时遇到问题。我可以在使用控制台时保存它-当我通过表单提交哈希值时它不起作用。
这个问题解决了它,但解决方案不适合我。此外,如果我使用:
serialize :bulk_action, Hash
我得到错误:
Attribute was supposed to be a Hash, but was a String
哈希值,当通过表单保存时看起来像这样:
"{"location"=>{"commands"=>{"custom_command_one"=>"true", "custom_command_two"=>"true"}}}"
然而,通过控制台:
{"location"=>{"commands"=>{"custom_command_one"=>"true", "custom_command_two"=>"true"}}}
我的数据库字段是一个文本字段。通过表单保存散列的最佳方法是什么?
—EDIT—
我发现如果我使用符号而不是字符串作为名称,我可以解决这个问题,但它仍然输出一个长字符串,而不是散列。
能否在文本区域内切换为JSON,这样解析它就不那么危险了。因为你需要做的是eval控制器或模型中各自的参数条目这让用户可以对运行你的应用的用户做任何他们想做的事。使用JSON,您可以在设置模型属性之前使用JSON.parse
。
我最近也遇到过这种错误。导致行为链为:
- 有一个具有可序列化字段
data
的模型 - 该字段必须存在(模型验证+ db约束)
- 因为db-constraint
NOT NULL
的sqlite db-adapter从构建矩阵失败,因为它不能允许默认值NULL
在NOT NULL
限制字段 - 由于sqlite,空字符串被设置为字段的默认值:
default: ''
- 初始化新模型时,在rails4上升级时使用
instance.data = ''
进行预置 - 但是保存此模型失败,错误消息为
“Attribute was supposed to be a Hash, but was a String”
,因为没有任何东西覆盖此错误字段值
解决方案:添加一个迁移:change_column :model, :data, :text, default: '--- {}'
作为一个有效的可序列化的空默认值
我也没有找到正确的答案。dump, to_yaml -在Rails 4.0.1中出现同样的错误)。只有eval对我有帮助。这不是一个大的安全问题,因为我在管理窗格中使用它。
params[:branch][:features_attributes][:primary] = eval params[:branch][:features_attributes][:primary]
params[:branch][:features_attributes][:secondary] = eval params[:branch][:features_attributes][:secondary]
if @branch.update_attributes(params[:branch]) ...
从链接http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize
serialize(attr_name, class_name = Object)
[...] The serialization is done through YAML.
所以列应该包含一个YAMLized版本的bulk_action但是'
"{"location"=>{"commands"=>{"custom_command_one"=>"true", "custom_command_two"=>"true"}}}"
不是一个YAML散列。如果你想处理原始的序列化数据,那么你应该使用像
这样的东西 "{"location"=>{"commands"=>{"custom_command_one"=>"true", "custom_command_two"=>"true"}}}".to_yaml