我经常这样写:
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
还有比这更简单更干净的吗?
弄个猴子围栏?
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
我不知道你认为你提出的解决方案有什么问题。我猜你想要一个 delete_all方法对散列或东西?如果是这样,Tadman 的回答提供了解决方案。但坦白地说,作为一次性的,我认为你的解决方案非常容易实现。如果您经常使用这种方法,那么您可能需要将它包装在一个 helper 方法中。
delete_all
用另一种方式来表达德马修的答案可能是
params.delete_if { |k,v| [:controller, :action, :other_key].include? k }
我对你最初在问题中发布的代码非常满意。
[:controller, :action, :other_key].each { |k| params.delete(k) }
我猜您不知道 ActiveSupport 添加到 Hash 的 除了方法。
它将使您的代码简化为:
redirect_to my_path(params.except(:controller, :action, :other_key))
而且,您也不需要猴子补丁,因为 Rails 团队已经为您做到了这一点!
当使用 Hash#except处理您的问题时,请注意它引入了 潜在的安全问题。处理来自访问者的任何数据的一个很好的经验法则是使用白名单方法。在这种情况下,改用 Hash#slice。
Hash#except
Hash#slice
params.slice!(:param_to_keep_1, :param_to_keep_2) redirect_to my_path(params)
从 Ruby 3.0开始,直接支持 Hash#except,这意味着我们不需要 activessupport 来访问 Hash#except。
来自文档:
除了(* key)→ Hash
此方法返回一个新散列,该散列包含除给定键之外的原始散列中的所有内容。
例如:
h = { a: 100, b: 200, c: 300, d: 400 } h.except(:a, :d) #=> {:b=>200, :c=>300}
参考文献:
Https://docs.ruby-lang.org/en/3.0.0/hash.html#method-i-except