Submit POST data from controller to another website in Rails
Asked Answered
I

5

54
  1. User submits a form with some basic data.

  2. The data is received and treated by an action in the controller and more information that needs to remain private is added.

  3. Then I need to send a post request to an external website with all of the combined data from the controller.

What is the best way to do this?

Intussusception answered 28/7, 2009 at 18:40 Comment(0)
T
88

The simpliest way is using ruby core library:

require "uri"
require "net/http"

params = {'box1' => 'Nothing is less important than which fork you use. Etiquette is the science of living. It embraces everything. It is ethics. It is honor. -Emily Post',
'button1' => 'Submit'
}
x = Net::HTTP.post_form(URI.parse('http://www.interlacken.com/webdbdev/ch05/formpost.asp'), params)
puts x.body

Pro Tip: Do an asynchronous request, using a gem like delayed_job or background_rb

Tightrope answered 28/7, 2009 at 19:10 Comment(4)
An example on using delayed_job on Ryan's railscast: railscasts.com/episodes/171-delayed-jobTightrope
This was the first thing I attempted. Unfortunately it gives me an 'end of file reached' error. From searching around it seems that others have had similar problems. Anyone have any insights?Intussusception
To solve EOF error when using https, see https://mcmap.net/q/136496/-eoferror-end-of-file-reached-issue-with-net-httpPushover
@VladZloteanu - why is your advice "do an asyncronius request, using a gem like delayed_job" ? thanksEmileemilee
I
34

Sorry, I neglected to mention that I was connecting to secure server. This seems to have been the reason that I was getting end of file errors. Adding using 'net/https' and calling use_ssl on connection solved the problem. Thanks for everyones help.

require 'net/https'
require 'open-uri'

url = URI.parse('https://MY_URL')
req = Net::HTTP::Post.new(url.path)
req.form_data = data
req.basic_auth url.user, url.password if url.user
con = Net::HTTP.new(url.host, url.port)
con.use_ssl = true
con.start {|http| http.request(req)}    

This is based off the source for the post_form method, so i guess I'll give vlad.zloteanu the answer.

Intussusception answered 29/7, 2009 at 15:52 Comment(3)
:) well.. 10qu, i'm glad it helped you.Tightrope
This seems to be working great, however I was expecting the controller to follow the redirection to the post as well, but it does not seems to be the case? Any any idea how I could do that?Sunless
Something I just worked out... setting the last line to response res = con.start {|http| http.request(req)} is useful.Granese
R
13

If the external server is RESTful, then simply create an ActiveResource model to handle your data.

Ruggles answered 30/7, 2009 at 12:43 Comment(0)
Q
6

I don't think redirect_to handles post requests because it uses http 302 (?) which just GETs the other page.

I believe you can do something like this

Class MyController < ActionController
    require 'net/http'

    def my_method
        #do something with the data/model

        my_connection = Net::HTTP.new('www.target.com', 80)
        reponse = my_connection.post(path_within_url, data)

        #do something with response if you want
    end

end

note: this is air coded and has not been tried or tested

Quintain answered 28/7, 2009 at 19:6 Comment(0)
F
1

If you want to send JSON, all you need is something like the following (tested in Rails 6):

Net::HTTP.post(
  URI('https://example.com/some/path'),
  { "this is the": "request body" }.to_json,
  'Content-Type' => 'application/json'
)
Filagree answered 3/6, 2020 at 3:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.