Question

I need to POST an array with HTTParty.

My array is [1, 2, 3] and the API expects to receive the body to be in the form

"story_hash=1&story_hash=2&story_hash=3"

It's not really important but here's the docs for the API in question.

The solution I have at the moment is:

params = [1, 2, 3].inject('') { |memo, h| memo += "&story_hash=#{h}" }
# Strip the first '&'
params.slice!(0)

options = { body: params }
HTTParty.post('/reader/mark_story_hashes_as_read', options)

Is there a better way (the ideal solution would be a feature of HTTParty that I just don't know of)?


I tried the following method:

options = {
  body: { story_hash: [1, 2, 3] }
}
HTTParty.post('/reader/mark_story_hashes_as_read', options)

But that seems to erroneously send a body like this:

"story_hash[]=1&story_hash[]=2&story_hash[]=3"
Was it helpful?

Solution

[1, 2, 3].map{|h| "story_hash=#{h}"}.join("&")
#=> "story_hash=1&story_hash=2&story_hash=3"

I would also recommend using CGI.escape(h.to_s) instead of h, it would encode the values for url (unless HTTParty already does that for you). So escaped version looks like:

[1, 2, 3].map{|h| "story_hash=#{CGI.escape(h.to_s)}"}.join("&")
#=> "story_hash=1&story_hash=2&story_hash=3"

OTHER TIPS

I agree with @tihom, just want to add that if you are going to use it more than once it would be good to override the query_string_normalizer method.

class ServiceWrapper
  include HTTParty

  query_string_normalizer proc { |query|
    query.map do |key, value|
      value.map {|v| "#{key}=#{v}"}
    end.join('&')
  }
end

You can use HTTParty::HashConversions.to_params method for this purpose

require "httparty"
HTTParty::HashConversions.to_params((1..3).map { |x| ["story_hash", x] })
# => story_hash=1&story_hash=2&story_hash=3
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top