Rails 5.如果设置了一个许可密钥,则不需要使用强参数

时间:2016-02-02 12:08:10

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

我正在使用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属性与强params相同,那么它确实有效。

我发送的JSON:

{
    "permit_attribute1": "data",
}

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

  

{“permit1”=>数据,“controller”=>“mycontroller”,“action”=>“创建”,“require_attribute”=> {“permit1”=> 1} }

似乎Rails使用必需的密钥创建哈希,而不是引发错误。 但是我想在收到JSON时强制使用必需的属性。

有人有想法吗?

2 个答案:

答案 0 :(得分:3)

  

强参数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的原因。相反,它是围绕导轨约定构建的,其中params嵌套在单个键下。

您可以使用'.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)

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

答案 1 :(得分:1)

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

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

这样,当所需的密钥不存在时,您将获得异常。