Sending Form data to remote rails application using Httparty
Okay I resolved it using Httparty itself. One thing which was making problems for me was form_for which is bounded to the rails model. So I used another form then just posted data using Httparty and on the remote app (Server side) I just retrieved each field and persist it. Very simple. Now I am a fan of Httparty!
Anyone who can suggest some good references for Httparty?
There aren't a lot of references out there for HTTParty. Primarily, the readme and examples in their github repo. You could potentially go through their code to get a feel as well. Here's a quick example of a post using the HTTParty mixin:
class Emailer
include HTTParty
base_uri 'api.emailer.com'
def send(username, password, to, subject, body)
options = { username: username,
password: password,
to: to,
subject: subject,
body: body }
post('/send', options)
end
end
While your question was about HTTParty, and I've had to use that in the past, I've generally liked Typheous better. You may want to take a peek at that. I'm sure there are plenty of other HTTP Clients out there too. Those are the two I've worked with, and I've tended to prefer Typheous.
POST to a Rails API using Rails and HTTParty
In the CitiesController, we are requiring :city in 'city_params'
def city_params
params.require(:city).permit(:name, :description)
end
But when calling the api, we missed passing :city
def new
@result = HTTParty.post('url_of_my_api_on_heroku/cities', :body => {:name => 'New York', :description => 'ABC'}.to_json, :headers => { 'Content-Type' => 'application/json' })
end
So, it should be:
def new
@result = HTTParty.post('url_of_my_api_on_heroku/cities', :body => {:city => {:name => 'New York', :description => 'ABC'}}.to_json, :headers => { 'Content-Type' => 'application/json' })
end
Very Basic Rails 4.1 API Call using HTTParty
Let's assume the API is in a JSON format and returns the data like so:
{"url": "http://example.com/unique-url"}
To keep things tidy and well structured, the API logic should belong in it's own class:
# lib/url_api.rb
require 'httparty'
class UrlApi
API_URL = 'http://example.com/create'
def unique_url
response = HTTParty.get(API_URL)
# TODO more error checking (500 error, etc)
json = JSON.parse(response.body)
json['url']
end
end
Then call that class in the controller:
require 'url_api'
class UniqueNumberController < ApplicationController
def create
api = UrlApi.new()
url = api.unique_url
@user = # Code to retrieve User
@user.update_attribute :url, url
# etc
end
end
Basically HTTParty returns a response object that contains the HTTP response data which includes both the headers and the actual content (.body
). The body contains a string of data that you can process as you like. In this case, we're parsing the string as JSON into a Ruby hash. If you need to customise the HTTP request to the API you can see all the options in the HTTParty documentation.
Creating Bulk Objects from Rails Form - Using Integer to Set Amount of Objects
In your create action you'd want to do something like this:
def create
@object.amount.times do |i|
object = Object.new do |object|
name = @object.name.strip # => "Basic"
number = (@object.start_at + i + 1) # => 2
formatted_number = number < 10 ? "0#{number}" : number # => "02"
object.name = @object.name.strip + formatted_number # => "Basic02"
end
object.save!
end
end
I've done a similar thing a few times, and this type of thing tends to mutate into an incomprehensible mess.
I'd suggest sticking this logic into a service object. That way you can abstract away any related logic and error handling, without bloating your controller, i.e.:
ObjectsController#create
:
def create
if CreateObjects.call(@object)
respond_to do |format|
format ... #success
end
else
respond_to do |format|
format ... #failure
end
end
end
and the CreateObjects
service:
# app/services/create_objects.rb
class CreateObjects
def self.call(object)
new(object).call
end
def initialize(object)
@object = object
end
def call
ActiveRecord::Base.transaction do # will only save if _all_ the objects are saved
@object.amount.times do |i|
create_object(i)
end
end
end
def create_object(i)
object = Object.new do |object|
name = @object.name.strip # => "Basic"
object.name = @object.name.strip + formatted_number(i) # => "Basic02"
end
object.save!
end
def formatted_number(i)
number = (@object.start_at + i + 1) # => 2
number < 10 ? "0#{number}" : number # => "02"
end
end
How to use basic authentication with httparty in a Rails app?
auth = {:username => "test", :password => "test"}
@blah = HTTParty.get("http://twitter.com/statuses/public_timeline.json",
:basic_auth => auth)
HTTParty - JSON to strongly typed object
It sounds like you want the return value of Myclass::get
to be an instance of Myclass
. If that's the case, you could cache the return value from the HTTP request and implement method_missing
to return values from that hash:
class Myclass
include HTTParty
attr_accessor :retrieved_values
def method_missing(method, *args, &block)
if retrieved_values.key?(method)
retrieved_values[method]
else
super
end
end
def self.get_with_massaging(url)
new.tap do |instance|
instance.retrieved_values = get_without_massaging(url)
end
end
class << self
alias_method :get_without_massaging, :get
alias_method :get, :get_with_massaging
end
end
This isn't exactly what you asked for, because it only works one level deep — i.e., x.questions[0].title
would need to be x.questions[0][:title]
x = Myclass.get('http://api.stackoverflow.com/1.0/questions?tags=HTTParty')
p x.total
p x.questions[0][:title]
Perhaps you could come up with some hybrid of this answer and Joshua Creek's to take advantage of OpenStruct.
I should also point out that all the method aliasing trickery isn't necessary if your method doesn't have to be named get
.
Related Topics
Invalid Source Reflection MACro :Has_Many :Through
How to Display Error Messages in a Multi-Model Form with Transaction
Rails "Template Is Missing" Error
Define a Class Method in a Module
Deleting a Line in a Text File
How to Merge Two Equally Sized Arrays into One Array with Sub-Arrays of Merged Values
One Line If Statement Not Working
Cocoapods Not Working in MACos High Sierra
Shoulda/Rspec Matchers - Conditional Validation
Count Overlapping Regex Matches in Perl or Ruby
How to Overwrite the '{ }' Object
Print Unicode Escape Codes from Variable
Deleting Blank Lines After Loop
How to Convert a Formatted String into Plain Text