Nimir Nimir - 5 months ago 14
Ruby Question

Ruby recursive method not working in Rails

I have a simple extension to Hash class, a method that deletes key-value pair if value is blank. It does that recursively for nested hashes as well.

Method:



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


To add to my Rails project, i put above code in
lib/core_ext/hash.rb
then required the file where i need. For this case i am trying to use it in a model concern.

Problem:



Running the
delete_blank
method from console works perfect, so:



{"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
#=> {}


However, in my Rails app, it does not remove blank pairs in nested hash, so:



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


Why the recursive part of the method does 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.instance_of?(Hash) || v.instance_of?(HashWithIndifferentAccess)) && v.delete_blank.empty? }
  end
end
Comments