为什么Rails参数包装不包含来自URI的全局内容?

Ash*_*she 8 ruby-on-rails actioncontroller

参数包装状态的文档:

将参数哈希包装到嵌套哈希中.这将允许客户端提交POST请求,而无需指定任何根元素.

它有助于省略包装哪些参数哈希.该动作控制器概述指南给出了这样的破败:

Rails收集与params散列中的请求一起发送的所有参数,无论它们是作为查询字符串还是帖子正文的一部分发送.[...] query_parameters哈希包含作为查询字符串的一部分发送的参数,而request_parameters哈希包含作为帖子正文的一部分发送的参数.所述path_parameters散列包含由所述路由为导致该特定控制器和动作路径的一部分可识别的参数.

当您使用RESTful资源和路由时,会发生这种乐趣.假设你有一个模型A has_many Bs; 因此B具有外键a_id.

POST /as/1/bs有一个空的有效负载(因为B没有其他字段).假设a_idattr_accessible,人们可能会认为a_id它将被包裹在一个b对象中.相反,你会看到:

Processing by BsController#create as HTML
  Parameters: {"b"=>{}, "a_id" => "1"}
Run Code Online (Sandbox Code Playgroud)

没有这样的运气.事实证明,ParamsWrapper使用request_parameters和不使用params,因此不包括a_idPOST有效负载意味着它不会被包装.这是非常令人困惑的,因为你仍然看到它包含在内params,因为URI通配,并想知道为什么它被排除在所有东西之外.

有没有什么好的理由可以使用request_parameters而不是params在这里?

我可以理解,从"REST哲学"的角度来看,如果我们假设有效载荷包含整个对象,它就更纯粹了,但这实际上意味着a_idURI中的内容被完全忽略,这似乎很可惜.

TL; DR: ParamsWrapper使用request_parameters作为参数源,所以URI-匹配替换的变量被跳过.这是一个Rails错误吗?纯REST倡导者可能会说不,但实用主义暗示是.

udi*_*tal 0

据我了解,a_id 未包含在“b”的哈希值中的原因是我们需要该 id 值来首先检查该记录是否存在于我们的数据库中。这样,我们就可以简单地拒绝请求中的其他参数。根据不将其包含在“b”哈希中的原因:它可以防止事故。考虑以下场景:假设有人正在更新表单并将完整的“b”哈希值作为参数传递给模型对象。现在,当我们调用 model_object.save 时,它​​可能会将记录保存在数据库中,而不是更新旧记录,这将构成安全威胁(如果对象已提前初始化,则可能会发生这种情况)。不是一个完整的证明场景,但编码时确实会发生事故,它可以帮助我们防止此类事故。