Rails form => URL => JSON => Save params - ruby-on-rails

This is basically what I want to do, with the params given in a form, I want to do a GET/POST request to a site, this site expects an specific URL like http://site.com/user=XXX&size=XXX and it will give me back a JSON, I want to parse/save the data from this JSON into my rails app when the form is submitted.
I am totally lost with this manner, anything would be very appreciated.
Rails Form Data => Build the URL => Do a GET/Post request => Catch JSON => Parse => Save

for rest api you can use activeresource in your application
http://api.rubyonrails.org/classes/ActiveResource/Base.html
if it's something very specific you can use Net::Http to make requests and then parse json to ruby objects by yourself.
Examples of using http://www.rubyinside.com/nethttp-cheat-sheet-2940.html
for decoding json you can use
Json or ActiveSupport::JSON.decode or this https://github.com/flori/json

I guess you want to do a request to another not your site to get the response. So you can install curb gem (the curl wrapper in ruby). Then use it to make the request on another site and parse json with standart RoR tools like Json to hash.

From http://www.rubyinside.com/nethttp-cheat-sheet-2940.html you get you can do the following:
at the top of your file add:
require "net/http"
require "uri"
require 'json'
then in your controller or helper:
#set the uri
uri = URI.parse("http://my.site.com/uri")
#set the post params and get the respons
response = Net::HTTP.post_form(uri, {"first_param" => "my param", "second_param" => "another param"})
#get the json info
data = JSON.parse(response.body)
#set result to an ActiveRecord (maybe there is a better way to do this, I guess it depends on the response you get
#something = Mymodel.new
#something.name = data["name"]
...
#something.save
Hope it helps!

Related

Params missing error when sending raw data in JSON Post for RSpec

I am trying to send some raw data in a JSON post request to my RSpec controller test. I have successfully tested the controller with an actual Postman request but I can't get the Rspec test to work
The error I am getting is
param is missing or the value is empty: annotations
Here is my test set-up, which I have copied verbatimly from rails server log when I run the request via Postman
params = '{annotations"=>[{"id"=>1, "location_start"=>1, "location_end"=>3, "source_text"=>"what", "reading"=>"cool"}, {"id"=>2, "location_start"=>1, "location_end"=>-1, "reading"=>"cool"}]}'
patch :update, params, format: :json
I have also tried
params = {:annotations => [{ :id=>1, :location_start=>1, :location_end=>3}]}
patch :update, params.to_json
https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs/controller-spec#setting-a-different-content-type-for-example-json-(request-type)
Check out how the json body is defined in this example: It's a ruby hash! So you need to not try passing in a raw string but a Hash that then gets automatically converted to JSON for you.
Hope that helps you out

Rails: Empty params when do ajax post with content-type = application/json

I used Backbone as Javascript framework for my new project. However, When I invoke save() on a Model , Rails server just can't parse it to the params hash
Javascript
user new Project.Models.User({email : "nqtien310#gmail.com"})
user.save()
Rails server
puts params
=> {"action"=>"create", "controller"=>"users"}
puts request.raw_post
=> "{\"email\":\"nqtien310#gmail.com\"}"
Then I tried to set Backbone.emulateJSON to true
Javascript
Backbone.emulateJSON = true
and Rails can parse the post data to params now, but not the expected data
puts params
=> {"model"=>"{\"email\":\"nqtien310#gmail.com\"}", "action"=>"create", "controller"=>"users"}
Well, after a long research , I figure it out that inside of my profiles' initialize/mime_types.rb , they added
Mime::Type.register "application/json", :mobile
Dig into a bit , I can see that Rails uses the mime types to parse the request body , in this case , application/json is overriden , and Rails can't use the Json parse strategy to parse the request body into params hash, that's why it's empty
Backbone.emulateJSOn will set another content-type instead of application/json, that's why Rails still can understand this Mime Type, and has correspond parse strategy for it , but since it's not the JSON strategy , so the params is not in JSON format
Json parse strategy ( from Rails source )
when :json
data = request.deep_munge ActiveSupport::JSON.decode(request.body)
request.body.rewind if request.body.respond_to?(:rewind)
data = {:_json => data} unless data.is_a?(Hash)
data.with_indifferent_access

Ruby on Rails: how to use OAuth2::AccessToken.post?

OAuth2::AccessToken.post() method is specified like this in the documentation:
(Object) post(path, opts = {}, &block)
I'm trying to pass some arguments, but seems that I*m doing it wrong:
response = token.post('/oauth/create.js', {:title => "title", :description => "desc"})
The parameters are never reaching the method, values are always nil. So, what is the correct way of using the post method with arguments? And what is that &block?
I'm also getting WARNING: Can't verify CSRF token authenticity. This might be contributing to the problem as well. The case is that I'm using OAuth api from the outside of the app. OAuth 2 is implemented via Doorkeeper gem.
Update: The CSRF warning is gone now after I defined scopes. Also I manage to use this post() method with arguments by providing the as part of the url: "?title=test&...". Still would be nice to know how to use this method as documented.
The body in a POST or PUT is accessed via the options body param. No documentation on this. Had to look in the oauth client code itself to discover this:
https://github.com/intridea/oauth2/blob/ebe4be038ec14b3496827d29cb224235e1c9f468/lib/oauth2/client.rb
Your example, with correct body would be:
response = token.post('/oauth/create.js', {body: {:title => "title", :description => "desc"}})
You can use the block to pass parameters to post request:
token.post('/oauth/create.js') do |request|
request.params['title'] = "something"
end
OAuth2 gem uses faraday, the request object is a faraday request, so you might want to check other ways to pass parameters along with the request
faraday gem => https://github.com/lostisland/faraday

Create record example for Quickbooks Online and Intuit Anywhere using Ruby and httparty?

Can someone post an example of creating a record in quickbooks online / intuit anywhere, using ruby and httparty?
I am working on an integration to a ruby on rails app using intuit anywhere, and am running into an issue with my POST request when attempting to create a new record. I have been able to successfully retrieve data (customers) using a POST command that doesn't require XML data in the body of the request, but am running into trouble when trying to create new records that have required fields that need to be passed in XML in the body of the request.
I get the same flavor of error in any entity for which I try to create a record for: an invalid or missing required field. It seems to me that the XML in the body (where the data for the required fields is added) is either being ignored (incorrect formatting?) or is not being attached.
I was hoping the someone else familiar with ruby could post an example of a record creation using httparty. If I could see how to correctly pass the XML using httparty, I can fix my problem myself.
I have been using the customer.com example (https://code.intuit.com/integration/viewvc/viewvc.cgi/IntuitAnywhere-Ruby/customer.com/?root=intuitanywhere&system=exsy1003) mostly as posted, with a few irrelevant modifications needed to get it to work in Rails 3.1. I am using the data pull and handling provided in the example, which looks like a pretty standard API wrapper built using httparty.
I am using a pull similar to the one found in the company_controller customers method. Here are two different ways I have tried submitting the XML:
#########################################
#Example 1 - XML
e = #company.intuit_token.post("https://qbo.intuit.com/qbo1/resource/account/v2/#{#company.realm}",
{ :body =>
"<Account xmlns:ns2=\"http://www.intuit.com/sb/cdm/qbo\" xmlns=\"http://www.intuit.com/sb/cdm/v2\">
<Name>Test Account 2</Name>
<Desc>Test Account</Desc>
<Subtype>Savings</Subtype>
<AcctNum>5001</AcctNum>
<OpeningBalanceDate>2010-05-14</OpeningBalanceDate>
</Account>",
:headers => {
"Content-Type" => "application/xml"
}}
)
#########################################
#Example 2 - hash
e = #company.intuit_token.post("https://qbo.intuit.com/qbo1/resource/account/v2/#{#company.realm}",
{ :body => {
:Account => {
:Name => "Loan Account 2",
:Desc => "Loac Account 2",
:Subtype => "Savings",
:AcctNum => "5001",
:OpeningBalanceDate => "2011-04-22"
}
},
:headers => {
"Content-Type" => "application/xml"
}}
)
I incorrectly assumed the customer.com example provided by intuit was using the httparty gem to make the POST call, so I was using the wrong syntax. They are actually using the OAuth gem's POST call, who's syntax can be found here: http://oauth.rubyforge.org/rdoc/classes/OAuth/AccessToken.html
I also had to modify the headers to get the Intuit Anywhere service to accept the XML body. Here is the code that finally worked for me to create a record in quickbooks online using intuit anywhere:
e = #company.intuit_token.post("https://qbo.intuit.com/qbo1/resource/account/v2/#{#company.realm}", "<Account xmlns:ns2=\"http://www.intuit.com/sb/cdm/qbo\" xmlns=\"http://www.intuit.com/sb/cdm/v2\"><Name>Test Account </Name><Desc>Test Account</Desc><Subtype>Savings</Subtype><AcctNum>5002</AcctNum><OpeningBalanceDate>2010-05-14</OpeningBalanceDate></Account>", {"Content-Type" => "application/xml", "standalone" => "yes", "encoding" => "UTF-8"})

How can I post xml data using net/http that also has data in the url

I am working with an api that requires me to post xml to url such as someapi.com?userID=123. Thus far, I have tried this (assume the xml is composed already in the xml variable):
url = URI.parse('http://www.someapi.com/process_leads.asp')
request = Net::HTTP::Post.new(url.path)
request.content_type = 'text/xml'
request.body = xml
request.set_form_data({'userID' => '1204'}, ';')
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
I am trying to figure out if I can have the userID as form data but also post xml? I am basically supposed to post the xml to http://www.someapi.com/process_leads.asp?userID=1204. Is that possible?
I would consider using a Http library, e.g. HTTParty
Example using HTTParty for your request would look something like:
HTTParty.post('http://www.someapi.com/process_leads.asp', :query => {:userID => 1024}, :body => xml )
the :query option takes a hash of key/values which will be added to the post URL,
the :body is where the xml goes.
NOTE: some api's require the xml to have a name e.g. you may have to do something like
:body => "request=#{xml}"
Hope this helps.

Resources