Nimir Nimir - 5 months ago 15
Ruby Question

Recursive method not working in Rails

I have a method1 on Hash that deletes key-value pairs whose value is blank. It does that recursively for nested hashes as well.

class Hash
def delete_blank
delete_if { |k, v| v.empty? || v.instance_of?(Hash) && v.delete_blank.empty? }
end
end


Running it from console works:

{
"customer_id"=>"foo",
"document_id"=>"",
"status"=>"",
"total"=>{"from"=>"1", "to"=>""}
}.delete_blank
#=> {"customer_id"=>"foo", "total"=>{"from"=>"1"}}

{
"customer_id"=>"",
"document_id"=>"",
"status"=>"",
"total"=>{"from"=>"", "to"=>""}
}.delete_blank
#=> {}


I put the code above in my Rails project in
lib/core_ext/hash.rb
, then required the file. I am trying to use it in a model concern. However, it does not remove blank pairs in nested hashes:

{
"customer_id"=>"",
"document_id"=>"",
"status"=>"",
"total"=>{"from"=>"", "to"=>""}
}.delete_blank
#=> {"total"=>{"from"=>"", "to"=>""}}


Why does the recursive part of the method not work as expected in the app (while it works in
rails c
)?

Answer

In some cases Rails uses HashWithIndifferentAccess class so I suppose your check v.instance_of?(Hash) can be false.

Workaround:

class Hash
  def delete_blank
    delete_if { |k, v| v.empty? || v.kind_of?(Hash) && v.delete_blank.empty? }
  end
end
Comments