Rails 5 API 强参数行为

Rails 5 API Strong Parameters behavior

前几天我生成了一个新的 rails 5 --api --database=postgresql 应用程序并且只创建了一个脚手架(Hero)。我想知道强参数在 rails 中是如何工作的,因为我看到了一些奇怪的行为:

控制器看起来像:

def create
  hero = Hero.new(hero_params)

  if hero.save
   render json: hero, status: :created, location: hero
  else
   render json: hero.errors, status: :unprocessable_entity
  end
end

我的 hero_params 看起来像这样:

def hero_params
  params.require(:hero).permit(:name)
end

所以我假设客户端需要提交一个包含 "hero" 键的散列,并且它允许有一个 "name" 子键,当这个控制器操作时允许批量分配被调用。

意思是,JSON 应该是这样的:

{
  "hero": {
    "name": "test"
  }
}

一切都很好,但我在这里看到了奇怪的行为。当用户如上提交确切的JSON时,参数进来为:

Parameters: {"hero"=>{"name"=>"test"}}

现在如果用户只提交:

{ "name": "test" }

它仍然创建一个新的资源,参数进来:

Parameters: {"name"=>"test", "hero"=>{"name"=>"test"}}
  1. 为什么会有两套参数,一套是实际提交的数据,一套是英雄对象的格式,好像是在等待群发?

  2. 为什么 require(:hero) 在未提交该密钥时不会引发错误?我认为这个问题的答案是因为什么自动创建了第二个哈希("hero"=>{"name"=>"test"}} 来自问题 1.

任何关于我在这里遗漏的信息都将不胜感激,因为这是准系统 rails 开箱即用的行为。

此行为来自 ActionController::ParamsWrapper

Wraps the parameters hash into a nested hash. This will allow clients to submit requests without having to specify any root elements.

Rails 应用程序默认为 JSON 请求激活参数包装。您可以通过编辑 config/initializers/wrap_parameters.rb 全局禁用它,或者通过在控制器中包含 wrap_parameters false 来禁用单个控制器。