Un truquito rápido.

Cuando desde un script Ruby queremos enviar un formulario por POST solemos usar la librería net/http y un método de alto nivel llamado post_form:

 require 'net/http'
 require 'uri'
 HTTP.post_form URI.parse('http://www.example.com/search.cgi'),
          { "q" => "ruby", "max" => "50" }
 

Sin embargo, cuando queremos hacer un envío más complejo, con parámetros compuestos (al estilo de los formularios generados por los helpers de Rails), ese método ya no vale, porque sólo soporta como parámetro un hash en el que claves y valores sean cadenas, y no otros hashes. Así que hemos de usar el método de más bajo nivel post, y encadenar los parámetros a mano, lo cual es un poco rollo.

Con esta pequeña (y fea ) extensión de la clase Hash es un poco más simple:

 module HashToHttpParams
   def to_http_params
     map do |k, v|
       if v.is_a?(Hash)
         v.map do |kk, vv|
           "#{k}[#{kk}]=#{vv}"
         end.join('&')
       else
         "#{k}=#{v}"
       end
     end.join('&')
   end
 end
 Hash.send(:include, HashToHttpParams)
 

Así que aunque tengamos que usar la forma "de bajo nivel", pues no es más complicado:

 my_params = {
  :post => {
    :body => "Bla!",
    :title => "Bla, bla, bla",
  },
  :tag => {
    :name => "bla"
  },
  :publish => "Publicar"
 }
 Net::HTTP.start("www.example.com") do |http|
   http.post("/posts/create", my_params.to_http_params)
 end
 

Y en otro momento cuento un truquete igual de quick & dirty para hacer esto mismo con autenticación, cuando el site no tiene el buen gusto de usar la autenticación HTTP (es decir, casi nunca ), y usa un sistema basado en cookies y sesiones.