2009-10-13 86 views
126

我经常发现自己写的:Ruby on Rails的:删除多个哈希键

params.delete(:controller) 
params.delete(:action) 
params.delete(:other_key) 
redirect_to my_path(params) 

删除的痕迹,感觉不对也不认为:

[:controller, :action, :other_key].each do |k| 
    params.delete(k) 
end 

有什么简单清洁器?

+0

当我写道第二种方法感觉不正确时,我的意思是说考虑到Hash API的丰富性,我怀疑这里有一些方法或习惯用法已经存在,而猴子补丁不会,没有必要。但也许不是。非常感谢所有回答的人! – 2009-10-13 15:08:28

+3

哈希#除了正是我正在寻找。我不记得这是一个Rails核心扩展,所以当我在Hash API中找不到它时我感到困惑。 – 2009-10-13 16:15:59

+1

请注意,严格来说,答案是'Hash#except!',但'除了'哈希#'是要走的路(不要混淆'params'!)。作为一个经验法则,除非绝对需要,否则不要混淆任何对象,副作用可能会有意想不到的结果。 – tokland 2013-08-19 11:36:04

回答

196

我猜你是不知道Hash#except方法的ActiveSupport增加散列。

它将使你的代码可以简化为:

redirect_to my_path(params.except(:controller, :action, :other_key)) 

此外,你就不必猴子补丁,因为Rails的团队做到了为您服务!

+1

啊,我知道我以前见过这个,但我不记得在哪里! (因此我的“这不正确”的评论。)谢谢! – 2009-10-13 16:10:13

+0

漂亮!必须记住这一个。 – Jim 2009-10-13 17:52:57

+3

这些较少记录的方法之一。我在提出答案的同时寻找这样的东西,但没有看到它。 – tadman 2009-10-13 21:41:21

8

打开猴子补丁?

class Hash 
    def delete_keys!(*keys) 
    keys.flatten.each do |k| 
     delete(k) 
    end 

    self 
    end 

    def delete_keys(*keys) 
    _dup = dup 
    keys.flatten.each do |k| 
     _dup.delete(k) 
    end 

    _dup 
    end 
end 
+4

猴子补丁是最后的手段。 – 2009-10-13 15:29:41

+14

替换现有功能的猴子补丁*是最后一招的工具。添加新函数的猴子补丁是Ruby 101. – 2009-10-13 15:33:09

+4

应该是'delete(k)'而不是'delete(key)' – Vincent 2010-12-29 02:26:23

2

我不知道你认为你提出的解决方案有什么问题。我想你想要一个delete_all方法在哈希或什么?如果是这样,tadman's answer提供了解决方案。但坦率地说,对于一次性,我认为你的解决方案非常容易遵循。如果你经常使用它,你可能想把它包装在一个辅助方法中。

10

另一种方式来短语dmathieu的答案可能是

params.delete_if { |k,v| [:controller, :action, :other_key].include? k } 
+2

我想你的意思是'params.delete_if {| k,v | [:controller,:action,:other_key] .include? k}' – Telemachus 2009-10-13 15:07:47

+0

好的,Telemachus。 – MikeSep 2013-07-29 16:23:56

20

我会与你同在最初发布在你的问题的代码完全满意。

[:controller, :action, :other_key].each { |k| params.delete(k) } 
+0

没有修改'哈希'这是最好的答案:+1: – 2016-02-01 20:53:01

40

虽然使用Hash#except可以解决您的问题,但请注意,它引入了potential security issues。处理来自访问者的任何数据的一个好的经验法则是使用白名单方法。在这种情况下,请使用Hash#slice

params.slice!(:param_to_remove_1, :param_to_remove_2) 
redirect_to my_path(params) 
+1

感谢您提到围绕重定向的安全问题。 – 2011-02-04 19:14:00

+11

只是个头:ActiveSupport,不是Ruby本身,提供了Hash#slice和#slice! http://as.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Slice.html – 2011-02-04 19:34:34

+1

我无法获得David James的工作链接,但这一个似乎没有问题:http://api.rubyonrails.org/类/ Hash.html#方法-I片 – 2014-05-22 14:47:57