I have a Rails app. I'd like to create a route that, in addition to doing some work in the controller and rendering a view, loads some data from another server to include as part of the response. Somewhat like a proxy, but with a bit of logic dependent on both the incoming request to rails and the data loaded from the other server.
Presumably, I'd issue some sort of HTTP request in the controller action, wait for a reply, and then make use of the result.
I'm interested in doing this entirely on the server — I do not want to use AJAX/CORS/etc on the client.
I'm curious as to whether there's a standard, somewhat official way of accomplishing this. I've seen a handful of examples using net/http — is this the "right" solution for the common case?
I'm not particularly worried about latencies, failure modes, asynchrony, streaming, or other advanced implementation details. Once I've got the basics down, then I'll happily layer in other fanciness to address any shortcomings.
Since you are not at all interested in implementing it using jquery or cor, then I think you may like to chose open-uri.
open("http://www.google.com").read returns the whole site as string, then you can do the parsing.
If the site is returning json then parsing will be even easier:
require 'open-uri'
require 'json'
def show
json = JSON.parse(open("https://graph.facebook.com/me/friends?access_token=XXX").read)
#name = json[:name]
#email = json[:email]
end
Related
I never before worked with API in Ruby on Rails so I'm pretty lost.
WHERE and HOW do I need to put this code.
GET http://api.bigcartel.com/mystore/products.json
Do I need to make a new products model and then write the API somewhere in application.yml
Thanks
There are a few ways you can work with an API from ruby. First if you are lucky maybe somebody already built a wrapper for that specific API. In this case there is one gem but it does not seem to be maintained any more. It might still work so feel free to try it out.
However you can also make HTTP requests by yourself. I prefer to use HTTParty gem. You could define a new class in /lib directory and build an API wrapper yourself, but let's start with a simple example.
response = HTTParty.get('http://api.bigcartel.com/mystore/products.json')
parsed_response_body = JSON.parse(response.body)
So here we first create an HTTP get request, and then parse the body to turn JSON into ruby hash.
Please notice that this is a very minimal example that assumes that everything will always go right. APIs often fail and unexpected things happen, don't forget to catch and handle exceptions that might occur.
I'm working on a web app with the client side made in Angular and the backend made in Ruby on Rails. The app will need to show a list of articles (dynamically generated data).
Here’s what I’m pondering about.
Online tutorials on building Angular apps coupled with Ruby on Rails are based on the following model of interactions between the client and the server. First, the client sends a request to the server, in response to which the server will send all the building blocks required to start up Angular, and then Angular will request all the missing data from the server. In my case, first Angular starts up then it requests a list of articles.
That's two request-response cycles, as illustrated by the following diagram.
What if, on the other hand, the server will during the very first response send the data necessary to display the initial view? Like, in my case, what if the first response also contained the first batch of articles to be somehow imported into Angular? Then there will be only one request-response cycle as shown on the following schematic:
Is this a good idea or a terrible one? And if it is not absolutely terrible, what is the way to import Rails’ instance variables (e.g. the first batch of articles sent as #articles) into Angular while it starts up?
(I found similar questions discussed — though very briefly and without any consensus reached — here and here.)
=======================
UPDATE:
OK, here is another StackOverflow discussion about this:
How to bootstrap data as it it were fetched by a $resource service in Angular.js
Is this a good idea or a terrible one?
I'd argue it's a Good Idea. It will improve your app's performance and requires minimally invasive changes. You could even configure your Angular app to conditionally make the requests in case the data isn't available on page load for some reason.
The Gon gem makes it trivial to use your controller instance vars in your views (as JS).
I have a rails application that uses Recurly for its transactions. I am trying to write automated tests for some of the helper functions that I have written.
A super simple example of a function...
def status_for_display
transaction.status.capitalize
end
In order to test these functions, I need to have a Recurly::Account object as well as associated Recurly::Transaction objects.
I have tried going the route of using Recurly::Account.create & Recurly::Transaction.create but I cannot seem to get the transactions to match up with the account.
I am also wondering if it doesn't just make better sense to use the VCR gem to make this happen. In which case, how would I go about doing that? I've never really managed to get VCR setup properly.
VCR is, by in large, plug and play. Once you have it configured and enabled, it'll intercept all HTTP requests and try to play back the data from a cassette. The problem with VCR, though, is that it is request data specific. In order for it to work right, you need to ensure that your tests are always sending the exact same request params to Recurly. You can work around this by having it skip certain things, but it's generally a pain.
The other option is to just use something like Webmock directly and house your own "known responses" for your Recurly calls, but then it's up to you to ensure that you responses stay in sync with the API.
In the end, I'd probably recommend going the VCR route but structuring your tests such that you have known good and bad test scenarios so you can get the real benefits of the cassettes.
I'm new to the rails world and am trying to build a app to simply allow me to search things on Amazon and such sites based on the users input.
I've done a little reasearch and it seems the httparty gem is a good place to start? The documents ive found so far though are not the best. They don't really give me a lot of information (where to put the code etc).
Are there any existing tutorials out there or code examples that I can either use or take a look at to give me a better idea of how this thing works?
I'm working on an app like this right now, so let me offer a few thoughts.
First, if you're a complete newcomer to Rails, then as a first step I'd suggest taking a parallel approach to the problem, with two tracks:
Learn about Rails
Learn about how to interact with an API (make requests and parse responses) in Ruby
These are two separate problems, and although you may end up implementing them together, it's best to think about them in isolation first.
For the first one, I'd suggest writing a couple simple apps first to get a feel for how things work. Even only a simple app will require a certain amount of user interaction, possibly saving records to the DB, etc., problems that are separate from consuming data from an API. There are an endless number of tutorials out there on Rails, but just to mention one, you might try Michael Harti's Learn Web Development with Rails as a starting point.
The second point, consuming API data, is distinct from the problems of designing the app itself. To learn more about this aspect of the problem, I'd suggest using a popular API client gem like (as you mentioned) HTTParty, which I use myself. Rather than immediately try to use the HTTParty methods in a Rails app, as an exercise I'd suggest playing around a bit in a console (irb). If you install the gem (gem install httparty) you can then require it (require 'httparty') from the console and immediately make requests and parse responses from the APIs.
E.g.:
irb(main):001:0> require 'httparty'
=> true
irb(main):002:0> response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
=> ...
Once you've got a bit more familiar with Rails and with accessing an API in ruby, then you could move on to actually building the app itself. Depending on how complex your requests to the API(s) are going to be, you have a few options as to how to structure your API requests in your Rails app:
Make the requests part of the Rails app itself, directly from controller actions. This is really only okay if you are only going to support a very limited number of request types (e.g. simple search) on a limited number of services. Anything more complex and your controller will get fat, which is a no-no in MVC frameworks.
Create a separate ruby class (usually called an API wrapper) to group together methods for making requests and parsing responses from the API. With a gem like HTTParty you can do this just by adding a line include HTTParty in the class, which adds the module to the class. There are lots of examples out there on how to do this, here is one.
Use a dedicated gem for accessing specific APIs, or create one (or more) yourself. There are gems for most popular services, e.g. Twitter, Linkedin, Flickr, etc. See this list of API client gems for more. This takes away a lot of the pain of interacting with an API, but will only work for a subset of all services.
You mention you're thinking of using HTTParty, which I can recommend as I am using it myself. There are alternatives such as Faraday (see this list of HTTP clients for more), but I find for most tasks HTTParty will do fine. The documentation may be a bit sparse, but there are a bunch of examples that you can work from.
Hope that helps!
I am a rails developer working on a cakephp site. The more work they send me, the more php code I write and thus the more dependence on php we introduce. What I want is to stop writing new features in php and start writing them in rails. Our resources are limited and the existing php site is huge so a full port from cake to rails is not possible.
Is there some way to write new features in a rails app while maintaining and allowing access to all the functionality of the old php (and vice-versa)?
It seems I would need a route aware app to traffic requests to either php or rails, but then we run into the issue of, for example, existing user functionality written in php not being available to the rails app and vice-versa.
What about something to translate ruby into php? That way I could start writing my model stuff in ruby/rails rather than php.
I feel like my question is muddled by the fact I do not know how to ask the questions I want to answer, so hopefully this is understood.
As always, thanks in advance!
One approach that you may find useful is to leverage the power of your web-server to properly re-write and delegate requests to two different systems. If you can design your new Rails application to use the same database records as the old one, with models mapping to the old tables directly, and ensuring that sessions established by one are valid in the other, you have a lot of latitude in how you go about doing this.
Apache has a very full-featured URL rewriting and proxying system that can be configured to direct "legacy" parts of your site to an existing set of PHP scripts while directing all other traffic to the new Rails application. You will need to be careful to ensure the design of both applications are nearly identical or it may seem strange to users.
Another approach that helps ensure a consistent appearance is to strip out a lot of the theme from your PHP application. By creating very bare-bones pages that only expose the required functionality on each page, Rails can fetch these by passing through any relevant session authentication information and re-frame them in the right layout.
This way you can preserve existing functionality and have it embedded inside your new application. You can use something as simple as open-uri or the curb gem to handle this HTTP-level delegation.
You would end up with controllers that look like this:
class PaymentController < ApplicationController
def index
#content = fetch_legacy_url('/payments/index.php'))
end
end
The fetch_legacy_url method would create an HTTP fetch request that includes the required headers, cookies, and so forth, and return the response body. Your view then ends up looking something like this:
<%= #content =>
From there you can shunt parts of the PHP layout over to the Rails app piece by piece. For instance, ripping out large chunks of static HTML and putting them in the Rails template would reduce the amount of actual PHP code you have to port.
It's a bit messy to maintain two applications in parallel, but as you point out the alternative is to keep accumulating technical debt and making the inevitable re-write that much more significant an undertaking.
The first step would be to experiment and see if you can create a Rails environment that uses your existing data, or at least the data relevant to the new functionality you intend to build out.