ruby-on-railsrubyruby-hash

Ruby change hash to single layer with square brackets


I've got a hash and I've found that with net/http posting I have to convert it into a flat format.

Example

invoice = { :no => "100", :date => "08/08/2022", :client => {:name => "Foo" } }

Would become

params = { "invoice[no]" => "100", "invoice[date]" => "08/08/2022", "invoice[client][name]" => "Foo" }

Is there a way to do this automatically? I've tried to_param & to_query, flatten and encode_www_form but they don't convert it to this required format.

The post action I'm doing is to a Ruby On Rails backend which I use Devise Tokens to authorise.

res = Net::HTTP.post_form(uri, params)

Solution

  • You need CGI.parse method. It parses an HTTP query string into a hash of key => value pairs

    CGI.parse({ invoice: invoice }.to_query)
    
    # => {"invoice[client][name]"=>["Foo"], "invoice[date]"=>["08/08/2022"], "invoice[no]"=>["100"]
    

    Don't care about single-element arrays as values. It will works well

    params = CGI.parse({ invoice: invoice }.to_query)
    res = Net::HTTP.post_form(uri, params)