如何解决弃用警告“方法 to_hash 已弃用并将在 Rails 5.1 中删除”
Posted
技术标签:
【中文标题】如何解决弃用警告“方法 to_hash 已弃用并将在 Rails 5.1 中删除”【英文标题】:How do I resolve the deprecation warning "Method to_hash is deprecated and will be removed in Rails 5.1" 【发布时间】:2016-12-07 05:53:38 【问题描述】:我正在尝试更新到 Rails 5,我收到以下弃用警告:
弃用警告:方法 to_hash 已弃用,将在 Rails 5.1 中删除,因为
ActionController::Parameters
不再继承自散列。使用这种已弃用的行为会暴露潜在的安全问题。如果您继续使用此方法,您可能会在您的应用程序中创建一个可被利用的安全漏洞。相反,请考虑使用以下未弃用的记录方法之一:http://api.rubyonrails.org/v5.0.0/classes/ActionController/Parameters.html(从 /Data/Projects/portal/trunk/app/helpers/application_helper.rb:114 的 column_header 调用)
警告所在的行如下所示:
link_to(name,
action: action_name,
params: params.merge( order: key, page: nil )
,
title: "Sort by this field",
) +
如您所见,我没有打电话给to_hash
。也许 Rails 是。也许其他一些宝石是。我无法判断,因为他们认为提供堆栈跟踪不值得。 (专业提示 - 通常值得提供堆栈跟踪!)
所以无论如何,我点击链接,计划寻找替代品,并 the merge
method does not appear to be deprecated,但也许他们只是忘记记录弃用状态,所以我不能确定。
那么我应该怎么做才能清除这个?
【问题讨论】:
是params.merge
还是link_to
调用to_hash
?
我至少查看了 params.merge,但事实并非如此。也许 link_to 会......在这种情况下,我可能会称这个 Rails 的错?我真的不知道。 (这正是为什么堆栈跟踪会很有用 - 我宁愿不必挖掘库资源来找出谁破坏了某些东西)
Debugger 建议 link_to
调用它,但我介入调查并且它非常深入。我设法验证url_for
调用它,但不知道在哪里。那么我的观点应该是他们不应该在自己的图书馆里这样做吗?我的意思是,我已经将一个参数对象传递给从参数生成链接的东西。看来这样做应该没问题。
您确定应该通过名为params
的参数将参数指定给url_for
,而不是直接在顶层传递参数,如:link_to(name, action: action_name, order: key, page: nil.merge(params)
?
如果你真的需要通过params: params
,试试params: params.to_h
。
【参考方案1】:
使用.to_h
您可以根据a comment on the Rails PR 调用.to_h
来获取安全哈希。
现在有三种方法可以将参数转换为哈希。
.to_h
的意思是“如果我没有打电话给.permit
,就假设什么都不允许。”
.to_unsafe_h
的意思是“如果我还没有打电话给 .permit
,就假设一切都是允许的。”
.to_hash
现在是模棱两可的。 Rails 将其视为.to_unsafe_h
,但会打印一个警告,因为您没有明确说明您想要上述两个选项中的哪一个。
首先,让我们看看如果您没有致电.permit
会发生什么。在 Rails 5.0 控制台中:
> params = ActionController::Parameters.new(yes: "y", no: "n")
> params.to_h
# empty hash because nothing has been permitted
> params.to_unsafe_h
"yes"=>"y", "no"=>"n" # raw values with no warning; you asked for it
> params.to_hash
# (puts deprecation warning - if you want unsafe values, say so)
"yes"=>"y", "no"=>"n" # returns raw values
但是,如果您先调用.permit
,将无法获取非允许值。
> params = ActionController::Parameters.new(yes: "y", no: "n")
> params = params.permit(:yes)
# (puts warning about unpermitted parameter :no)
> params.to_h
"yes"=>"y" # permitted values only
> params.to_unsafe_h
"yes"=>"y" # permitted values only
> params.to_hash
# (puts deprecation warning, but still safe)
"yes"=>"y" # permitted values only
所以:
-
始终使用
.permit
将您期望的值列入白名单
使用.to_h
确保如果您忘记了第 1 步,任何事情都不会通过
如果您真的想要原始值,请不要调用.permit
并调用.to_unsafe_hash
不要打电话给.to_hash
,因为这现在很模糊
【讨论】:
我想有了这个,我将不得不使用 to_unsafe_hash - to_h 正如你所说,只返回允许的内容,但我在库代码中我不知道允许哪些参数。因此,我为使用许可所做的任何事情都需要迭代所有密钥,这似乎与 to_unsafe_hash 一样糟糕。另外,我所做的只是生成一个最终将再次成为参数的 URL。 url_for不能使用Parameters本身就太可惜了,不过哦。 嗯。如果您在库代码中,您从哪里获得参数?如果应用程序正在调用您的库,他们应该在将参数交给您之前调用.permit
,对吗?您可以使用params.permitted?
进行检查。我会担心用任意参数构建一个 URL,尤其是在你不知道它们来自哪里的库代码中。
参数来自控制器,但有问题的哈希用于过滤和排序,我想我一定不是热衷于复制代码以允许所有过滤器的完整列表。我必须想出某种方法以某种方式以编程方式拉出列表。 ://
我不明白为什么这个答案被投了赞成票,因为尽管提供了一个很好的解释,但它根本没有回答这个问题(OP 想知道 - 就像我一样 - 谁/在哪里调用了 .to_hash首先
@sandre89 问题是“我收到以下弃用警告......(详细信息)那么我应该怎么做才能清除它?”以上是关于如何解决弃用警告“方法 to_hash 已弃用并将在 Rails 5.1 中删除”的主要内容,如果未能解决你的问题,请参考以下文章
如何修复“UIPopoverController 已弃用”警告?
如何解决“VisibleDeprecationWarning:zmq.eventloop.minitornado 已弃用”?