【问题标题】:Rails hashes with unknown keys and strong parameters带有未知键和强参数的 Rails 哈希
【发布时间】:2013-10-10 23:02:42
【问题描述】:

我有一个 Rails 应用程序,它在名为 properties 的字段中存储序列化哈希。

虽然哈希键是未知的,所以我不知道有一种方法可以使用强参数来实现这一点。

在谷歌上搜索时,我发现了这个:https://github.com/rails/rails/issues/9454,但我无法确切知道解决方案是什么。

所以基本上,我的问题是:如何配置强参数以允许具有未知键的哈希?

感谢大家的帮助!

【问题讨论】:

  • Ehm,那么不要使用强参数?我的意思是,在这种情况下它们不是没用吗?
  • 您可以将接受的答案更新为@jpwynn
  • @SergioTulentsev 在这种情况下并不是真的没用,因为他想允许属性“属性”本身(并忽略它本身是带有未知键的哈希的事实)。所以他想允许/白名单那个参数,而不是它的孩子。

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


【解决方案1】:

您可以使用散列代替符号并定义允许的子属性。 这可以在源代码中看到:

case filter
when Symbol, String
  permitted_scalar_filter(params, filter)
when Hash
  hash_filter(params, filter)
end

https://github.com/rails/rails/blob/bdc73a438a97f2e0aceeb745f4a95f95514c4aa6/actionpack/lib/action_controller/metal/strong_parameters.rb#L522

例如

def user_params
  params.require(:person).permit(:name, :description, :age, properties: [:key, :value])
end

如果您不知道properties 中的内容,您可以使用.slice。请注意,这也将接受嵌套在任何其他字段中的任何内容。

例如

def user_params
  params.require(:person).slice(:name, :description, :age, :properties) 
end

这些方法适用于以下参数:

{
  "person": {
    "name": "John",
    "description": "has custom_attributes",
    "age": 42,
    "properties": [
      {
        "key": "the key",
        "value": "the value"
      }
    ]
  }
}

我已确认这些将在 Rails 4.2.6 上工作

【讨论】:

    【解决方案2】:

    这些答案都不适合我(使用 Rails 4.2.4),所以我想出了以下解决方法:

    def product_params properties_keys = params[:product][:properties].keys params.require(:product).permit(:title, :description, properties: properties_keys) end

    希望对某人有所帮助。

    【讨论】:

    • 帮了大忙!尽管在 Rails 5 中需要使用字符串,而不是符号,例如:params['product']['properties'].keys
    • 很好的答案,这适用于 5.0.2 与 @jpwynn 的建议
    【解决方案3】:

    我最近遇到了同样的问题,我使用https://github.com/rails/rails/issues/9454的@fxn 方法解决了它

    对于以properties为哈希的产品,将其解决为

    def product_params
      params.require(:product).permit(:title, :description).tap do |whitelisted|
        whitelisted[:properties] = params[:product][:properties]
      end
    end
    

    如果您在environment 中使用:raise 而不是:log 代替config.action_controller.action_on_unpermitted_parameters,请记住在调用permit 之前从params 中删除properties。那么方法就是

    def product_params
      properties = params[:product].delete(:properties)
      params.require(:product).permit(:title, :description).tap do |whitelisted|
        whitelisted[:properties] = properties
      end
    end
    

    【讨论】:

    • 缺失的部分:首先使用delete从参数中删除哈希数据
    【解决方案4】:

    您的需求与强参数的目标完全相反, 当我们定义强参数时,基本上我们会将即将到来的参数列入白名单。

    在你的情况下,我们完全不知道密钥,所以 没有必要在那里进行强参数检查。这将解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      • 2016-10-25
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多