如何解决弃用警告“方法 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 中删除”的主要内容,如果未能解决你的问题,请参考以下文章

警告 onRowClick 已弃用

如何修复“UIPopoverController 已弃用”警告?

如何解决“VisibleDeprecationWarning:zmq.eventloop.minitornado 已弃用”?

如何解决 React Native 的警告信息

如何在 Flex 3 中禁用已弃用的警告?

如何修复弃用警告:类级别方法将不再继承 Rails 6.1 中的范围?