Design pattern to integrate Rails with a Comet server - ruby-on-rails

I have a Ruby on Rails (2.3.5) application and an APE (Ajax Push Engine) server. When records are created within the Rails application, i need to push the new record out on applicable channels to the APE server. Records can be created in the rails app by the traditional path through the controller's create action, or it can be created by several event machines that are constantly monitoring various inputstream and creating records when they see data that meets a certain criteria.
It seems to me that the best/right place to put the code that pushes the data out to the APE server (which in turn pushes it out to the clients) is in the Model's after_create hook (since not all record creations will flow through the controller's create action).
The final caveat is I want to push a piece of formatted HTML out to the APE server (rather than a JSON representation of the data). The reason I want to do this is 1) I already have logic to produce the desired layout in existing partials 2) I don't want to create a javascript implementation of the partials (javascript that takes a JSON object and creates all the HTML around it for presentation). This would quickly become a maintenance nightmare.
The problem with this is it would require "rendering" partials from within the Model (which im having trouble doing anyhow because they don't seem to have access to Helpers when they're rendered in this manner).
Anyhow - Just wondering what the right way to go about organizing all of this is.
Thanks

After talking w some folks in #rails and #ape this is appears to be the best approach to this issue.

Related

Migrating from rails app to backbone.marionette app

I'm a new in backbone.marionette. I read some guides, but not enough understood how is the MVC structure implemented there.
In rails I'm having structure like this:
app/
assets/
controllers/
models/
views/
config/
environmrnts/
development.rb
staging.rb
production.rb
routs.rb
log/
my view/js files are sending data to controller(during update/create and more), and and also getting data from it. the controller sends requests to model in another rails app, using Api class(that all the models are inherit from it) with net/https.
My questions are:
1. How do I implement the connection with the other app in backbone.marionette?
2. Is the idea of the mvc is the same as in rails? what actually the controller does in marionette?
3. How should my app structure look like?
4. Where should I store config parameters?
It goes through the API you define in the Rails app. Each Backbone model will define a url property to indicate where its data is stored. Then Backbone will take care of the rest (e.g. sending a POST request to the API to create a new model instance in the DB)
The idea is similar, but not the same. In Backbone, the controller and model behave mostly as in Rails apps. Collections are a group of models that you work with to make it easier in your app (e.g. displaying a list of users). Templates are sort of like views in Rails : they define the HTML markup that will get generated. Views in Backbone are very different : they react to the environment (e.g. user clicks, data modification) and drive the app's behavior. This doesn't happen in Rails apps because the page gets rendered and sent back : there is no itnteraction (eacch user click will make the server generate a new page and send it to the user).
It depends. There are many valid approaches, and you can see one here : https://github.com/davidsulc/marionette-gentle-introduction
It depends :-) Quite often, you will stroe them in a simple javascript object.
If you want something to guide you on your journey learning to develop javascript apps, take a look at these :
backbonerails.com uses Rails and Marionette to develop an application
my book on Marionette focuses more on explaining the various bits and pieces of Marionette, as well as how and when to use them
You can see an example of connecting to a different service using an API here : http://www.backbonerails.com/screencasts/loading-views starting at the 6:00 mark. The url property is defined at 9:40, but note that this case requires the url to be different for each collection instance, which might not be true in your case. If all collection instances have the same url, you'd simply define it as a property on the collection "class".

How to use EventMachine(superfeeder-ruby gem) within a Rails controller?

thank you for taking a look at this.
I am new to rails, unfortunately. I currently have to implement an endpoint that Superfeedr can push updates to, but that endpoint has to be in a rails controller.
Initially it seemed to me that this should be a background job that runs and the rest of the web tends to agree, but I am being pressured to include this as a rails controller - which confuses me. I am not certain how to include EventMachine in a request/response cycle.
I know the web is full of examples, but none really answer my question with how to route this. I have no idea.
I have a rails controller, called Superfeeds. I want Superfeeder to push updates to something like myrailsapp/superfeeds/
Inside feeds I want to inspect the pushed content, and then write the results of that to another controller that actually has a model and will persist it.
Basically, the controller called Feeds just needs to receive and pass the information along. This confuses me however because it seems to have to implement something which is a long running process inside of a rails controller - and I am not even sure if this can work.
Does anyone know of a way that this has been done with rails, but not using EventMachine as a background job? In the end I really just need to know that this is possible.
-L
Inside feeds I want to inspect the pushed content, and then write the results of that to another controller that actually has a model and will persist it.
Why not do all the work in the one controller? If you're trying to separate out different concerns, you could even use two models - for instance one to do the inspecting/parsing and one to handle the persisting. But rarely would you need or want to to pass data from controller to controller.
I am not certain how to include EventMachine in a request/response cycle.
Never used superfeedr myself, but glanced at the docs quickly - are you using the XMPP or PubSubHubbBub client? I assume the latter? If so, you want to do the persistence (and any other time-consuming process) async (outside the request/resp cycle), right?
If you are using an EventMachine-based webserver such as Thin, basically every request cycle is run within an EM reactor. So you can make use of EM's facilities for offloading tasks such as the deferred thread pool. For an example of this in action, check out Enigmamachine, in particular here. (I believe that in addition your db client library needs to be asynchronous.)

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.

Ruby on Rails MVC Question

I intend to store in a database a minimal amount of information pertaining to a book (title, isbn). However, on display I'd like to display additional attributes (pages, author, cover image) not stored in the database. I plan on getting this information from the Amazon Web Services (AWS) using Ruby/AWS. I am very new to Ruby on Rails and am not sure exactly how this would/should be performed.
Some options that spring to mind include modifying the books controller or creating an entirely separate model based on the Amazon entities that relies upon searching for books listed only in my database.
Your ActiveRecord book model can be customized to retrieve the additional attributes from AWS. Your view and controllers will be clueless and DRY.
When you ever need to deal with any data, in any MVC environment, it needs to go in the model. You could create an additional other_information method that uses ||= to either get the other information from AWS or returns the information from an instance variable. Either that or you could create a find_with_info method that gets it all at the same time :)
But defiantly keep any data-related tasks in the model.
I would suggest creating methods in the model. Are you always going to be pulling the extra info every time you show these entries? If not you will want to maybe have a different controller action for either the "extended" (ie with amazon info) or "limited" (ie without the amazon info) and have the other be the standard. This way you can pull exactly what you want when you want it and make sure you hit amazon only when you need to, not with every single show or index call.

Resources