“属性应该是哈希,但是是一个字符串”

时间:2013-05-19 20:08:08

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

我在Rails 3应用程序中保存哈希时遇到问题。我可以在使用控制台时保存它 - 当我通过表单提交哈希时它就不起作用了。

This SO question addresses但是解决方案对我不起作用。而且,如果我使用:

 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"}}}

我的数据库字段是文本字段。通过表单保存哈希的最佳方法是什么?

- 编辑 -

我发现如果我使用符号而不是字符串作为名称但我仍然可以输出一个长字符串,而不是哈希值,我可以解决这个问题。

4 个答案:

答案 0 :(得分:1)

你可以在textarea中切换到JSON,这样解析它就不那么危险了。因为你需要做的是评估控制器或模型中相应的params条目,使用户能够与运行应用程序的用户一起做任何他们想做的事情。使用JSON,您可以在设置模型属性之前使用JSON.parse

答案 1 :(得分:0)

我也没有找到正确的答案(YAML.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]) ...        

答案 2 :(得分:0)

从链接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.

因此该列应包含bulk_action的YAMLized版本,但是

 "{\"location\"=>{\"commands\"=>{\"custom_command_one\"=>\"true\", \"custom_command_two\"=>\"true\"}}}"

不是YAML哈希。如果你想要使用原始序列化数据,那么你应该使用像

这样的东西
 "{\"location\"=>{\"commands\"=>{\"custom_command_one\"=>\"true\", \"custom_command_two\"=>\"true\"}}}".to_yaml

答案 3 :(得分:0)

我最近也遇到过这种错误。引起行动的链条是:

  • 有一个带有可序列化字段data
  • 的模型
  • 该字段必须存在(模型验证+ db-constraint)
  • 由于db-constraint NOT NULL,构建矩阵中的sqlite db-adapter失败,因为它不允许NULL受限字段<上的默认值NOT NULL / LI>
  • 因为sqlite,空字符串被设置为字段的默认值:default: ''
  • 初始化新模型时,我们在rails4
  • 上进行了升级时预设了instance.data = ''
  • 但保存此模型失败并显示错误消息“Attribute was supposed to be a Hash, but was a String”,因为没有任何覆盖此错误字段值的内容

解决方案: - 使用:change_column :model, :data, :text, default: '--- {}'添加迁移作为有效的可序列化空默认值