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

Есть ли что-нибудь более простое и чистое?

Ответ 1

Я предполагаю, что вы не знаете о Hash # except метод ActiveSupport добавляет к Hash.

Это упростит ваш код:

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

Кроме того, у вас не было бы патча обезьяны, так как команда Rails сделала это для вас!

Ответ 2

При использовании Hash#except устраняет вашу проблему, имейте в виду, что она представляет потенциальные проблемы безопасности. Хорошим правилом для обработки любых данных от посетителей является использование белого списка. В этом случае вместо этого используйте Hash#slice.

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

Ответ 3

Я был бы полностью доволен кодом, который вы изначально разместили в своем вопросе.

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

Ответ 4

Другим способом выражения ответа dmathieu может быть

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

Ответ 5

Запустите патч обезьяны?

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

Ответ 6

Я не знаю, что вы считаете неправильным в своем предлагаемом решении. Я полагаю, вы хотите использовать метод delete_all для Hash или что-то еще? Если да, то ответ tadman предоставляет решение. Но, честно говоря, для одноразового, я думаю, ваше решение очень легко следовать. Если вы используете это часто, вы можете его обернуть в вспомогательном методе.