views:

521

answers:

4

Hi, I am using Pommo for my mailing list, unfortunatelly Pommo doesn't provide an HTTP API but provides and embedable subscription form I can put on my site. But posting using that form takes me out of my site and that is unacceptable for me.

So I want to do the field validation in Rails and then use curl to post the values.

The fields Pommo generates looks like this:

   <input type="text" size="32" maxlength="60" name="Email" id="email" value="" />
   <input type="text" size="32" name="d[1]" id="field1" />
   <input type="text" size="32" name="d[2]" id="field2" />
   <input type="text" size="32" name="d[3]" id="field3" value="México" />

Which produces the following params in Rails:

   { "d"=>{"1"=>"Macario", "2"=>"Ortega", "3"=>"México", "5"=>""}, "Email" => [email protected] ... }

Now I can validate the format of the email and if the required fields are present but I don't know how to encode this hash as string for posting using curl.

Is this kind of data structure encoding standar or dependant on application? Does it has a name?

A: 

you should be able to do an HTTP post from inside your rails application

http = Net::HTTP.new('localhost', '3030') result = http.post('/process_email_form', form_param_hash).

You can validate this approach by viewing the HTTP Header and parameter information generated from the Pommo form against what you internal application posts

Aaron Saunders
A: 

That'll be called a "serialization" Serialization, and in this case, it's most likely dependent on Rails (I come from a PHP background).

Chris
+2  A: 

That format is created by Rails with the function normalize_params. Basically it recursively interprets [] as hashes. You can find the code at the Rails API page.

Here is a very rough sample function to undo it for your case:

def create_post_params(params, base = "")
  toreturn = ''
  params.each_key do |key|
    keystring = base.blank? ? key : "#{base}[#{key}]"
    toreturn << (params[key].class == Hash ? create_post_params(params[key], keystring) : "#{keystring}=#{CGI.escape(params[key])}&")
  end
  toreturn
end

I haven't really tested it, but it does about what you want. You can then use it with something like curl. But you can also use the built in Ruby Net::HTTP lib.
Something like:

@server = URI.parse(server_url)
http = Net::HTTP.new(@server.host, @server.port)
http.use_ssl = @server.is_a?(URI::HTTPS)
result = http.post(@server.path + "PATH TO METHOD IN SERVER", create_post_params(params), SOME_HEADER_OPTIONS)

I would also recommend you looking at a project called HTTParty. It is a library to make easy HTTP API classes for services.

ScottD
A: 

ActiveSupport (available for free under Rails) provides a handy to_param method.

{ "d"=>{"1"=>"Macario", "2"=>"Ortega", "3"=>"Mxico", "5"=>""}, "Email" => "[email protected]" }.to_param
# => "Email=mail%40example.com&d%5B1%5D=Macario&d%5B2%5D=Ortega&d%5B3%5D=Mxico&d%5B5%5D="
Simone Carletti