Calling application from rails - ruby-on-rails

I have an existing website/application that uses COBOL-CGI where the COBOL app creates the html pages by filling in data using placeholders.
I now want to create a rails site that in addition to using its own db, should also call the external application to retrieve various information.
Can this application still be called using cgi?
Is there a better way to call 3rd party applications from rails? ActiveX?

You probably want to do it a little differently. You can have the Rails application call the COBOL CGI, but the current one is creating HTML, which you'd need to scrape for the data.
Probably you'd be best off to modify the COBOL to generate some simpler representation, down to and including just a CSV file, although YAML or JSON might be a little easier to use. Then you can invoke the COBOL application, and capture its output for use by the rails application.

Related

Restrictions on user-submitted code

I have a Ruby on Rails application, and one of its functions is to present JSON data to the user in table form. Before this step, I intend to add a way for users to tweak the JSON data by means of uploading their own Ruby code files that handle this.
This has its dangers. I definitely don't want any form of access (reading or writing) to the databases, nor do I want it to be able to call anything in another file. How can I limit the file in this way?
Essentially all I need is for the main code to call the function in the user-submitted file with the JSON as the parameter, and returning JSON back. All logic during this manipulation of the JSON must happen in and only in the user file.
I've looked around for ways to do this with no luck. I've seen this question:
Restricting access to user submitted code in Rails
The issue here is that I'd prefer an approach that doesn't require a gem. Also sandboxing seems rather complicated for the approach I want, which is a blanket restriction, and not specific things.
I intend to raise the $SAFE level to 4 before calling the user-supplied code/method. That doesn't seem to prevent calling other methods in the application though.

What is the difference between a regular Rails app and a Rails API?

In the process of learning Rails, I read about how we could combine it with some front-end MV* JavaScript frameworks — such as Backbone.js, Angular.js, or Ember.js — to improve the UX.
This introduced (to me) the concept of using Rails as an API, instead of a web app.
So, now, I am pretty confused: what is the difference between a regular Rails app and a Rails API?
According to the official rails website, there are three main differences between a rails web application and a rails api:
1 - The api app is configured to start with a more limited set of middlewares than normal. Specifically, it will not include any middleware primarily useful for browser applications (like cookies support) by default
2 - In the api app, ApplicationController inherits from ActionController::API instead of ActionController::Base. As with middlewares, this will leave out any Action Controller modules that provide functionalities primarily used by browser applications.
3 - The api app is configures the generators to skip generating views, helpers and assets when you generate a new resource.
You can always convert your rails app from either one of these to the other one. To do so, follow the steps in the reference I mentioned above.
A regular Rails app will use the rails views (erb or haml) to render pages directly. That is to say, it will process the data AND render this data in views, answering directly the client request with a HTML page.
A Rails API will just process your action, and assume someone else is doing the job of rendering the view for the client. Therefore, a Rails API is expected to return data in an appropriate format, like JSON, XML, or just a JS piece of code to execute. It is then the job of frontend frameworks like AngularJS to receive, parse, and do something with the data (like update some HTML, etc.)
In a nutshell,
Classic Rails application are all-in-one applications, where the processing and rendering are both handled by Rails. The apps may lack or responsiveness however, as full pages are rendered, but it's usually much faster to code this way.
Rails API are just serving intermediate results. It will focus on just delivering the data. This can be better if you have strong requirements for the design/responsiveness, as you are more flexible with the frontend libraries you can use. Usually only the data is transferred, so in addition it can be faster. There are some problems with APIs. For example with one-page apps + full AJAX, it may be harder to set up a forward/back behavior on the user browser. Also, using APIs will require more work, but if you have many devs, you can agree on the interfaces, and parallelize the work server/frontend.
Now, it's not a black or white answer I'm giving. You can totally have a Rails app mainly built as a Web app, but with some API actions that give more responsiveness to some pages. An exemple of this, is to have an autocomplete form, that is pulling the data via AJAX calls.
I found a pretty clear answer in Yoni Weisbrod's Rails API Mini Guide:
The fundamental difference between an API and a regular Rails app is
that an API returns data for further processing, rather than data that
is meant to be viewed directly. Therefore, rather than producing an
HTML document (with CSS and/or Javascript) that looks pretty, APIs
produce simple information structures that can be further processed by
whatever will be consuming our API.

Using AngularJS in Ruby on Rails app

I have a existing project in Ruby on Rails.
What is the best way to use AngularJS in Ruby on Rails app?
I want to use AngularJs for only specified modules, not for create SPA. This is good way?
What I have seen colleagues do in order to achieve this sort of integration with an existing rails app is:
Include angular.js and relevant dependencies in the specific app pages that are to be 'angularized'
Interpolate whatever data is needed to bootstrap the angular controller into the html template which contains the angular app. This might include data about the resource being operated on. I've seen this done by rendering a RABL template inside of a haml/erb template.
Using that interpolated data, call whatever API methods you need to get additional data on the fly. This is usually just a matter of implementing json handlers for routes you've already created.
I can't say whether this is best practice, but its an easy way to get started fast.
Best of luck, angular is a very enjoyable tool to work with once you get used to it.

Rails app with non-HTTP access

Hypothetical question (at the moment!)
Suppose I have a great idea for an application. It acts on data which can be well-represented by tables in a relational database, using interlinked objects which represent those tables. It supports a well-defined API for interacting with (Creating, Reading, Updating, Deleting) those objects, and viewing information about them.
In short, it's a perfect fit for Rails... except it doesn't want to be a web-app. Perhaps it wants a Command Line interface; or an OS-native dialog-based interface; or perhaps it wants to present itself as a resource to other apps. Whatever - it just isn't designed to present itself over HTTP.
These questions suggest it's certainly possible, but both approach the problem from the point of view of adapting an existing web-app to have an additional, non-web, interface.
I'm interested in knowing what the best way to create such an app would be. Would you be best to rails new non_web_app, in order to get the skeleton built "for free", then write some "normal" Ruby code that requires config/environment - but then you have a lot of web-centric cruft that you don't need? Or would it be better to roll up your sleeves and build it from whole cloth, taking just the libraries you need and manually writing any required configuration?
If the latter, what exactly is needed to make a Rails app, but without the web bits?
If you want to access the Rails ORM to develop a CRUD non-web application, just include ActiveRecord in your own Ruby script; you will avoid using a lot of Rails modules you probably don't need (routing, template generator, ...) Here is an example of how to do it.
If you prefer to have the full Rails stack, do not run your Rails web app in an application server (WEBrick, Passenger, Mongrel, ...) to avoid any HTTP exposure, and interact with your application using tasks or the rails console.
I would avoid taking Rails too far off the rails. If I were doing this and felt that the gains of rails w/o the web stuff I'd do the following:
rails new non_web_app
and ignore the webbish cruft and use rails to generate models. In this way you get the tight, comfortable database behavior and can tie various gems in as you want to augment those models. I'd not bother implementing views, of course, and I'd consider implementing controllers in which the various render bits are removed and to use you instantiate an instance of the controller and call the action directly. This means the controller represents your API into your business logic still but the "views" it now "renders" are simply the return of the data output.
Then you could simply strip out the bits you do not need...the public directory, the view structure under app, config/routes.rb, etc. You'll need to test those changes incrementally and make sure that removing some now extraneous bit doesn't throw the Rails world into chaos.
Rails is for Web apps. That means HTTP. Now, you could package a Web app so that it runs on the desktop instead, or you could use ActiveRecord with a desktop application framework like Monkeybars.

CakePHP and Rails: slowly port old php functionality to new rails

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.

Resources