2012-08-22 9 views
7

docs on parameter wrapping状态:为什么Rails参数包装中不包含从URI中循环播放的东西?

裹参数散列到嵌套散列。这将允许客户端提交POST请求,而不必指定任何根元素。

它有用地消除其中参数散列被包裹。该Action Controller overview guide给这个破败:

的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"} 

没有这样的运气。事实证明,ParamsWrapper uses request_parameters而不是params,所以在POST有效负载中不包括a_id意味着它不会被包装。这非常令人困惑,因为您仍然看到它包含在params中,这是由于URI通配,并且奇怪为什么它排除了所有内容。

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

我可以理解,从“REST哲学”的角度来看,如果我们假设有效载荷包含整个对象,那么它更纯粹,但这基本上意味着URI中的a_id被完全忽略,这似乎是可怜。

tl; dr:ParamsWrapper使用request_parameters作为参数源,因此会跳过URI- globbed变量。这是一个Rails错误?纯粹的REST倡导者可能会说不,但实用主义表明是的。

+0

你好!你有没有想过如何解决这个问题? – dan

+1

@dan:不幸的是,自从我发布这个问题几个月后,我还没有与Rails合作过,所以我一无所有! – Ashe

回答

0

据我所知,a_id未包含在'b'的散列中的原因是我们需要该id值来首先检查记录是否存在于我们的数据库中。这样,我们可以简单地拒绝请求中的其他参数。根据不包括在'b'杂志中的理由:它可以防止事故发生。假设有人正在更新表单并将完整的'b'散列作为参数传递给模型对象。现在,当我们调用model_object.save时,它可以将记录保存在数据库中,而不是更新将成为安全威胁的旧记录(如果对象已经初始化,可能会发生)。不是一个完整的证明方案,但编码时确实发生了事故,它可以帮助我们防止这种事故。

0

取决于您的具体的使用情况,但如果你在你的控制器使用强大的参数,可以,你可以做任何

params[:b][:a_id] = params[:a_id] 
params.require(:b).permit(:a_id) 

或只是跳过完全是“规定”的方法:

params.permit(:a_id) 
相关问题