1

I have two different kinds of hashes:

hash1 = {"h1_k1": "h1_v1", "h1_k2": ["h1_v2"]}
hash2 = {"h2_k1": "h2_v1", "h2_k2": "h2_v2"}

I may have numerous occurences of each hash with different values, but the following issue occurs even with a single occurence of each:

I want to send the data to a Rails server in an HTTP post request, and the behavior differs when I send it in a single request for the entire data and in one request per hash.

In the controller, params will be the following:

Single request: I push both hashes into an array and Net::HTTP.post_form(uri, array).

Parameters: {"{\"h1_k1\"=>\"h1_v1\", \"h1_k2"\"=>"=>{"\"h1_v2"\""=>{"}"=>nil}, {\"h2_k1\"=>\"h2_v1\", {\"h2_k2\"=>\"h2_v2\"}"=>nil}

One request per hash: array.each {|hash| Net::HTTP.post_form(uri, hash) }

Parameters: {"h1_k1": "h1_v1", "h1_k2": "h1_v2"} # array converted to string of only the last element
Parameters: {"h2_k1": "h2_v1", "h2_k2": "h2_v2"}

What is the reason behind this, and is there any way to properly send the data in a single request?

Akra
  • 265
  • 2
  • 10

2 Answers2

1

In the definition of post_form(url, params):

The form data must be provided as a Hash mapping from String to String

In your example, you have an Array that contains two hashes. Consider passing the params as Hash.

Gilg Him
  • 842
  • 10
  • 19
  • 1
    So given I may have several occurences of the same hash format to send (ex 5 hash1's and one hash2), this means I must send one hash per POST request. – Akra Jul 17 '19 at 19:29
  • No, you could post with multiple values according to the docu too. params could be hashes separated by a commas. – Gilg Him Jul 18 '19 at 19:31
  • 1
    Example from the docu: ` res = Net::HTTP.post_form(uri, 'q' => ['ruby', 'perl'], 'max' => '50') ` Notice that the params are a hash mapping from String to String or array of strings. So you have two ways, either push the tow hashes to an array, after transforming them to string type and post one param like this `post_form(url, "h1" : [hash1.to_s, hash2.to_s])`:, or you could assign the two hashes to two different keys and post them as well. post_form(url, "h1" : hash1.to_s, "h2": hash2.to_s)` – Gilg Him Jul 18 '19 at 19:36
1

I ended up solving it in two different ways:

  1. I used to_json on the array and I set the header Content-Type to be application/json. This allowed instant access to the properly formatted array and hashes in the server side params[:_json]. For example params[:_json][0]['h1_k1'] gives h1_v1.

  2. I used to_yaml on the array and I set the header Content-Type to any of the YAML options. The params in the backend side were empty as (I guess) Rails couldn't parse it automatically, but using request.raw_post allowed to get the data from the post body. Thus using Psych.safe_load(request.raw_post) parsed it back into an array of hashes, which allowed the use of the data just like in method 1 (disregarding params).

Akra
  • 265
  • 2
  • 10