Ruby modify elements of nested hashes
<p>I have a RoR application in which at some point I recieve some params in the form of a hash. There's a field <code>amount</code> repeated within the hash. I want the value of these fields inverted.
This is an example of the nested hash:</p>

<pre><code>{"name"=&gt;"asdasd", "rate_type"=&gt;"DependantRate",
 "category_rate_requests_attributes"=&gt;{
   "0"=&gt;{
     "date_from"=&gt;"2016-08-03", "date_to"=&gt;"2016-08-03",
     "room_category_rates_attributes"=&gt;{
       "0"=&gt;{"r_id"=&gt;"7", "amount"=&gt;"5"},
       "1"=&gt;{"r_id"=&gt;"98", "amount"=&gt;"15"},
       "2"=&gt;{"r_id"=&gt;"3", "amount"=&gt;"25"},
       "3"=&gt;{"r_id"=&gt;"1", "amount"=&gt;"35"},
       "4"=&gt;{"r_id"=&gt;"115", "amount"=&gt;"45"},
       "5"=&gt;{"r_id"=&gt;"116", "amount"=&gt;"55"},
       "6"=&gt;{"r_id"=&gt;"117", "amount"=&gt;"65"}
     }
   },
   "1"=&gt;{
     "date_from"=&gt;"2016-08-05", "date_to"=&gt;"2016-08-07",
     "room_category_rates_attributes"=&gt;{
       "0"=&gt;{"r_id"=&gt;"7", "amount"=&gt;"3"},
       "1"=&gt;{"r_id"=&gt;"98", "amount"=&gt;"13"},
       "2"=&gt;{"r_id"=&gt;"3", "amount"=&gt;"23"},
       "3"=&gt;{"r_id"=&gt;"1", "amount"=&gt;"33"},
       "4"=&gt;{"r_id"=&gt;"115", "amount"=&gt;"43"},
       "5"=&gt;{"r_id"=&gt;"116", "amount"=&gt;"53"},
       "6"=&gt;{"r_id"=&gt;"117", "amount"=&gt;"63"}
     }
   }
 }
}
</code></pre>

<p>And I want to obtain a new hash which has that <code>amount</code>field with the same values but negative, as in:</p>

<pre><code>{"name"=&gt;"asdasd", "rate_type"=&gt;"DependantRate",
 "category_rate_requests_attributes"=&gt;{
   "0"=&gt;{
     "date_from"=&gt;"2016-08-03", "date_to"=&gt;"2016-08-03",
     "room_category_rates_attributes"=&gt;{
       "0"=&gt;{"r_id"=&gt;"7", "amount"=&gt;-5},
       "1"=&gt;{"r_id"=&gt;"98", "amount"=&gt;-15},
       "2"=&gt;{"r_id"=&gt;"3", "amount"=&gt;-25},
       "3"=&gt;{"r_id"=&gt;"1", "amount"=&gt;-35},
       "4"=&gt;{"r_id"=&gt;"115", "amount"=&gt;-45},
       "5"=&gt;{"r_id"=&gt;"116", "amount"=&gt;-55},
       "6"=&gt;{"r_id"=&gt;"117", "amount"=&gt;-65}
     }
   },
   "1"=&gt;{
     "date_from"=&gt;"2016-08-05", "date_to"=&gt;"2016-08-07",
     "room_category_rates_attributes"=&gt;{
       "0"=&gt;{"r_id"=&gt;"7", "amount"=&gt;-3},
       "1"=&gt;{"r_id"=&gt;"98", "amount"=&gt;-13},
       "2"=&gt;{"r_id"=&gt;"3", "amount"=&gt;-23},
       "3"=&gt;{"r_id"=&gt;"1", "amount"=&gt;-33},
       "4"=&gt;{"r_id"=&gt;"115", "amount"=&gt;-43},
       "5"=&gt;{"r_id"=&gt;"116", "amount"=&gt;-53},
       "6"=&gt;{"r_id"=&gt;"117", "amount"=&gt;-63}
     }
   }
 }
}
</code></pre>

<p>(yes, the values are now numbers but it doesn't really matter if they are strings or numbers as long as they are negative).</p>

<p>This is what I've came up with:</p>

<pre><code>rate_params[:category_rate_requests_attributes].try(:each) do |_key1, category_rate_request|
  category_rate_request[:room_category_rates_attributes].each do |_key2, room_category_rate|
    room_category_rate[:amount] = room_category_rate[:amount].to_i * -1
  end
end
</code></pre>

<p>But it's far from nice code.</p>

<p>Any suggestions on what would be the best way to do this?</p>