【问题标题】:Rails 5. Strong params require not used if one permit key is setRails 5. 如果设置了一个许可键,则不需要使用强参数
【发布时间】:2016-02-02 12:08:09
【问题描述】:

我正在使用 Rails 5 创建 JSON Api。

我的控制器使用带有一个 require 属性的强参数,如下所示:

params.require(:require_attribute).permit(:permit_attribute1,:permit_attribute2)

通常我必须像这样发送我的 JSON:

{
    "require_attribute":{
        "permit_attribute1": "data",
        "permit_attribute2": "data"
    }
}

如果缺少必需的属性,我必须得到这个消息:

"ActionController::ParameterMissing: param is missing or the value is empty: require_attribute"

我的问题是,如果我从 JSON 中删除所需的属性并且我有一个 permit 属性与强参数相同,它确实有效。

我发送的 JSON:

{
    "permit_attribute1": "data",
}

当我在log 中获得 params 时,我有:

{"permit1"=>data, "controller"=>"mycontroller", "action"=>"create", "require_attribute"=>{"permit1"=>1}}

Rails 似乎创建了一个带有所需键的哈希而不是引发错误。 但我想在收到 JSON 时强制使用 required 属性。

有人有想法吗?

【问题讨论】:

  • 你用什么来发送那个“更简单”的 json?是否有角度/静止角度?
  • 我在控制台或 Postman 插件中使用 curl

标签: ruby-on-rails ruby strong-parameters rails-api ruby-on-rails-5


【解决方案1】:

强大的参数 API 是针对最常见的用例设计的 心里。它并不意味着可以作为解决所有问题的灵丹妙药 白名单问题。

http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters

require(key)

确保参数存在。如果存在,则返回 给定键的参数,否则引发 ActionController::ParameterMissing 错误。

http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-require

从上面可以看出,在“平面”哈希上设置所需参数并不是强参数 API 的真正用途。而是围绕参数嵌套在单个键下的 rails 约定构建的。

您可以使用“.require”一次拉出一个键,但这会相当笨拙。

您可以通过引发异常来模拟它的作用,除非密钥存在:

def something_params
  req = [:required_attribute1, :required_attribute2]
  req.each do |k|
    raise ActionController::ParameterMissing.new(k) unless params[k].present?
  end
  whitelisted = params.permit(:permit_attribute1, :permit_attribute2)
end

然而,更好的方法可能是使用模型级别的验证 - ActionController::ParameterMissing 应该表示请求的一般格式已关闭 - 而不是缺少必需的属性。例如,对于 JSONAPI.org 格式的请求,您可以这样做:

params.require(:data).require(:attributes).permit(:email, :username)

确保请求符合标准。但是,强制在没有电子邮件的情况下无法创建用户是模型级别的问题。

【讨论】:

  • 好吧,但是为什么require 在所需的密钥不存在时不会引发错误?这似乎是这里的预期行为。
  • 不,不是。考虑到参数在 rails 甚至将请求与路由匹配并实例化控制器之前就已写入日志。我不确定错误是您发送请求的方式,还是 Rack 或某些中间件强制请求参数的一些非常奇怪的问题。
  • 同样.require实际上并没有修改request.params。它返回一个副本。如果你检查服务器日志并且参数看起来像你有一些可疑的事情发生。
【解决方案2】:

是的,默认情况下,API 模式下的 Rails 将 JSON 请求参数包装到一个哈希中,从控制器类中猜测其名称。你可以阅读详情here。

如果您的应用不需要此功能,只需从config\initializers\wrap_parameters.rb 中的:format 数组中删除:json。或者,您可以在控制器级别使用细粒度控制,如上所述。

这样,当所需的密钥不存在时,您会得到一个异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-13
    • 2019-09-17
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2017-04-04
    • 1970-01-01
    相关资源
    最近更新 更多