【问题标题】:"Attribute was supposed to be a Hash, but was a String"“属性应该是一个哈希,但它是一个字符串”
【发布时间】:2013-05-14 09:20:01
【问题描述】:

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

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

-- 编辑--

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

【问题讨论】:

  • 你使用什么表单标签来输入哈希:input、textarea、...?
  • @moritz 尝试了文本区域和文本输入,但没有成功。想知道是否可能是haml在做某事,但这似乎有些牵强。甚至在 MySql 中切换到 blob 类型。

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


【解决方案1】:

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

【讨论】:

  • 只是在试验。当您说切换到 JSON 时,您的意思是在保存/更新之前解析控制器中的字段。例如:params[:payload] = JSON.parse(params[:payload])
  • 我想我可能会删除该字段。并手动输入。它只是为超级管理员设计的,而不是为最终用户设计的......
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    来自链接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 的 YAML 化版本,但 '

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

    不是 YAML 哈希。如果您想处理原始序列化数据,那么您应该使用类似

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

    【讨论】:

      【解决方案4】:

      我最近也遇到了这种错误。导致行动的链条是:

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

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

      【讨论】:

        猜你喜欢
        • 2018-04-29
        • 2017-02-14
        • 2012-05-03
        • 1970-01-01
        • 1970-01-01
        • 2017-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多