Rails display JSON from an api GET request - ruby-on-rails

I'm a rails beginner and I'm trying to display a json object I get back from an external api. I'm using HTTParty and I'm almost positive I have that set up correctly. I have a function in my HTTParty class called
self.get_all()
How would I go about making a new page on which to display the JSON I get back from that function?

It all pretty much depends on the json that comes back. Aside from it being 'JSON`, what does it look like? If you haven't even inspected it yet, maybe that's a good place to start. You can call your method like so: (pick one)
puts your_httparty_class.get_all.inpsect # will be displayed in your logs (most likely)
raise your_httparty_class.get_all.inspect # will raise the response to the view
You may find yourself needing to do something like this to ensure it's a hash.
response = HTTParty.get('https://api.somesite.com/some_endpoint')
body = JSON.parse(response.body)
Now that you know and can see that the JSON is just a hash you can access it like so:
something = body[:something] # accessing a hash
nested_something = body[:something][:nested_something] # accessing a nested hash
You can then move something and nested_something around your app. So, you could pass it from your controller to your view as instance variables:
# # makes it an instance variable and therefore accessible to your controller's views
#something = body[:something]
#nested_something = body[:something][:nested_something]

Related

How to pass large data set between controllers in Rails

Currently passing retrieved data using redirect_to which uses GET. Since in some cases data set is large, URI is too long and throws Bad Request error.
All online research says its a bad idea to pass data in GET body. Is there a better way to pass data to another controller?
Code Block
def create
response_body = http_get('/data/I/want')
parsed_result = JSON.parse(response_body)
check_response(parsed_result)
redirect_to controller: :search_results, action: :index, results: parsed_result
end
end point called in create is search results so need to check if results are empty before redirecting and passing the data. I omitted this part from the code block
Any reason to put these code in create method? From my point of view, your code doesn't really create anything. It is just get some JSON data from a remote URL and redirect to search_results#index. Why not just load the JSON in search_results#index directly?
Update
It is too generous to use more than 3 routes for a search action. I have two suggestions:
Search in remote JSON if you can control it. Just pass the searching keyword in URL and let remote resolve it.
If you cannot control the remote JSON, do the search with AJAX call. In your search_results#index, makes an AJAX call to your something like search#new JSON route and fetch the filtered result.

How param works in rails views

I have an old app running in rails 2.3.5
In customizing, I stuck when i find a param keyword being used in views
i.e in views I can see stuffs like
unless params[:fee_collection].nil?
can someone explain to me in what context is param keyword used in rail views rather than controllers
params is a hash that contains parameters sent with the HTTP request.
You can access to this object as well from your controller or from a view. Although, the convention is to access to an instance variable (defined in your controller, e.g : #fee_collection = params[:fee_collection]) from your view.
The params variable stores a hash which contains the http parameters received in the request to this route (controller#action)
If you have a UserController with the show method, you should receive the param[:id] to identify the resource you're looking for.
If you want to send parameters, it would be either via url in a GET or a data payload on a POST request, on the most common cases.

How do I get environment variables in Rails from inside a gem?

I'm making a Ruby on Rails gem and need access to variables like cookie or the query parameters. How do I get this from inside a gem?
module MyModule
def self.my_method
# need access to cookies, query params, etc
end
end
So that from a controller or view, I can call
MyModule.my_method
and it'll have the access it needs.
You need to pass in what you want. Whether you want to pass in each individually or pass in the request object and pull out what you want depends on how/where you'll use your gem. I would lean towards passing in each individually in a well defined format so there aren't any surprises b/n rails servers and what the request object looks like.

Generate XML dynamically and post it to a web service in Rails

I am currently developing a Rails app in which I need to dynamically send XML request to an external web service. I've never done this before and I a bit lost.
More precisely I need to send requests to my logistic partner when the status of an order is updated. For instance when an order is confirmed I need to send data such as the customer's address, the pickup address, etc...
I intended to use the XML builder to dynamically generate the request and Net:HTTP or HTTParty to post the request, based on this example.
Is that the right way to do so? How can I generate the XML request outside the controller and then use it in HTTParty or Net:HTTP?
Thanks for your help,
Clem
That method will work just fine.
As for how to get the XML where you need it, just pass it around like any other data. You can use the Builder representation, which will automatically convert to a String as appropriate, or you can pass around a stringified (to_s) version of the Builder object.
If, for example, it makes sense for your model (which we'll call OrderStatus) to generate the XML, and for your controller to post the request:
# Model (order_status.rb)
def to_xml
xml = Builder::XmlMarkup.new
... # Your code here
xml
end
# Controller (order_statuses_controller.rb)
def some_method
#order_status = OrderStatus.find(:some_criteria)
... # Your code here
http = Net::HTTP.new("www.thewebservicedomain.com")
response = http.post("/some/path/here", #order_status.to_xml)
end
You may want to wrap the HTTP calls in a begin/rescue/end block and do something with the response, but otherwise it's all pretty straightforward and simple.
Make XML with Builder, then send it down the wire.
In your case it sounds like you may need to send several different requests as the order evolves; in that case:
Plan out what your possible order states are.
Determine what data needs to be sent for each state.
Decide how to represent that state within your models, so you can send the appropriate request when the state changes.
Where my example uses one method to generate XML, maybe you'll want 5 methods to handle 5 possible order states.

Make Rails return response from other local URL

I want a /plan method to return a json object that's itself returned by another local (but belonging to another web app in java) URL (let's call it /plan2 for the sake of this question).
What I want is not a redirect but really to have /plan return the data as it is returned by /plan2, to which I'm appending a bunch of other keys. Since the request is local, would using Net::HTTP be overkill? What are my options, considering I'd also like to send an HTTP Accept header along.
Shooting in the dark here, but I am assuming that /plan belongs to public Rails app and the /plan2 is the url from another web app (maybe not even Rails) on the same server accessible by Rails app but not publicly available. If this is the case, then yes, you can get the response, but I would suggest rather OpenURI or Mechanize than Net::HTTP. If you put it in respond_to JSON format block then everything should be fine with Accept header also.
are you speaking of re-using functionality of another controller-method?
there is no standard way of doing this in rails. you could either put the common functionality into a module and include it this way, or use inheritance if the functionality is in another controller. if it's the same controller class, you could just call the method.
if it's a "private" url, how are you going to call it via http?!
I would suggest encapsulating whatever functionality /plan2 uses and simply re-use that in /plan1
But if you just want to get it to work...
class PlanController < ApplicationController
def plan1
plan2(extra_parameter_1: true, extra_parameter_2: 'hello')
end
def plan2(extra = {})
params.merge!(extra)
# Whatever your code was before...
end
end

Resources