What is the best practical way to add a major feature/service to an existing medium-sized Ruby on Rails project? - ruby-on-rails

I have an existing project written in Ruby on Rails. It is sort of backend solution for the upcoming major addition to the project. What I mean is it currently serves for the admins and it already has loads of features and actual Rails files in there.
Now I am planning to add the new "Public" facing part of the App in Rails and I am wondering what could be the best solutions. I could think of the two following possible ones but I would really appreciate if anyone who had experienced this could put me in the right direction.
Create a new Public facing Web App using the same resources the backend Web App was using - any pros and cons?
Simply add the new features to the existing backend Web App - any pros and cons? (I am sure this option will make the App files grow quite large, but should I care? or not?
I have only done small Web Apps in Rails before and this is my first large one. Please, anyone, your answers will be much appreciated.
Thanks.

You already have a lot of business logic in the models, so starting a new application would mean duplicating that logic, which is a maintenance nightmare.
I would simply add the public facing parts on to your existing project. I wouldn't worry about the application getting big. I've worked on a very large rails application and it works fine. (177 tables/models, 23+ controllers, etc...)
Just make sure you create a good way to separate the internal parts from the external ones, by adding a field to the User model to indicate if they are internal or external, and then as part of the authentication, limiting access to the internal parts.

Related

Ruby on Rails separate front & back

I've been using Ruby on Rails since a little more than one year now and I've always do it in a casual way, I mean, everything in one place (front & back), using the standard .html.erb file populated by the associated controller method.
Otherwise, today in our project, I have the need to separate the front and the back end for multiples reasons (code maintainability / clarity, better architecture, more reactivity, etc...).
I've done plenty of researches, watch some conferences (1, 2, 3), but didn't find my solution yet. It looks like to be a question that comes often, but what is the best practice/tools to separate the backend and the frontend of a Ruby on Rails app?
I don't feel we need (yet) a huge JS framework like React/EmberJS/Angular/etc...
First I was thinking about something like Middleman/Jekyll and make the communication via JSON and API calls, but it seems like that it's not a good solution for dynamic website.
So is there a frontend framework that works well with a Rails API and which is easily maintainable and upgradable (add feature/extension to it like gems)?
Thanks for your insights.
A friend of mine wrote this great article/tutorial on Rails as a backend API.
http://blog.launchacademy.com/the-basics-of-building-an-api-in-ruby-on-rails/
As well as this tutorial on Rails/Ember.js
https://github.com/diegodesouza/Project-Planner-EmberJS
You can get an idea of how it's done and implement your preferred front end framework.
Hope it sheds some light on this question.
I have a similar setup as one of the commenters on the question.
I'm using Rails mainly for just the project structure, to define some page layouts, and for ActiveRecord.
I then have my JSON APIs defined using the Grape API framework.
I have a SPA, written on AngularJS that lives in the public/ folder. It doubles as my mobile app, made possible by phonegap. If my Angular app didn't double as my mobile app, I could've possibly just used the asset pipeline to serve up the SPA. To compensate for that, I have a separate build task written in Grunt to minify/uglify my JS/CSS assets before I deploy them out to production.
I also use Comfortable Mexican Sofa for my static content pages.
It took some trial and error to get things right, but overall I find that this setup serves me pretty well.

Rails application architecture and common setup

So I am starting out on company project that will have several components:
At first...
Job list
Client profile creation and management
User administration and access (login, signup, roles, etc)
later...
Messaging
Schedule
Basic reporting
way later...
Deeper analysis and bi
I'm wondering if it makes sense for each bullet item to be its own rails project, self contained and modular (if that is indeed the case); or if it's just best for it to be in the same app. I could envision a situation where each module could operate so independently of each other that it wouldn't need the rest (except for the user funcionality) and another situation where all modules would be used together.
It seems like to me that many tasks can be handled with a lighter framework like Sinatra (and then situated physically under the rails app). It also seems like it would be a lot of overhead to have several rails apps running on a server. But I am not totally aware of all the pluses and minuses to operating each scenario.
I know this is kind of a general question that is bound to get a lot of "it depends" kind of responses (and rightfully so) I was looking for opinions/examples of how you setup this kind/your kind of project in rails. I am a quasi noob so be gentle.
Thanks in advance!
Generally speaking I would consider a website to be a suitable target for a Rails app. Each part of the app can have its own namespaces within the app, so the app has some structure internally, but they should all be one application. Consider things like sessions, where you want a user to login and use whatever features of the site you want. You want those sessions in one application without a user having to login to different sections.
Saying that, if there is complex or extended functionality that isn't part of the MVC architecture (say talking to an external API, data-mining etc), then you could offset that to a separate project and a include it as a Gem in your application. You would still have one main Rails application that includes those Gems.
You might also want to bundle together a section of your project into a reusable Rails engine that can be loaded into multiple projects. For example, Devise handles user login and management. It is a Rails engine, bundled as a Gem, that you include in your project.
Another example from Meducation (one of my sites). I'm in the process of extracting our email tracking system out into its own Rails engine as I feel its functionality sits alongside Meducation and is not a core part of it. I can then use it in other projects as well.
In your specific example, I think your requirements fit fine in one Rails application.

Rails: Re-using models, controllers and even views between Rails applications

I have a rails app which contains some fairly generic functionality (eg managing users). I would like to use that common functionality in other rails apps without copying it. The hard part seems to be that this code contains a number of models, controllers and views.
I know that gems and plug-ins allow code to be shared but they seem to apply more to sharing utility and library functionality rather than core parts of an app.
Any advice on how to do this would be greatly appreciated.
We are working with a Rails engine to share functionality between client projects and have gotten quite far with it. The engine contains controllers, models, views, and even routes. It provides core functions needed in each project (access to our in-house content management system) so projects don't have to start from scratch.
Most of the code has been structured in a way that it can be easily extended or overwritten where needed in the projects (mostly by subclassing). It's distributed as gem.
I can't show you code (it's not open-source), but I can point you to some helpful resources:
Rails 3 Plugins - Part 1 - The Big Picture
Rails 3 Plugins - Part 2 - Writing an Engine
Rails::Engine documentation
Plugin Authors: Toward a Better Future
Hope this helps!
Making copies is not always bad. That's why I ask about the reasons you don't want to copy the code.
If you create a 'library', you must ensure that every application will use it in the same manner. Or you have to prepare the 'library' for every possible difference between your applications which use it.
If you share the code, you are adding a dependency to your program. Any change in that shared code will affect more than one application.
Often it's much simpler to copy the code to another application, because then your may apply any modification without thinking about others.
Are you sure that managing users is so generic that you will not make any application-specific changes to it?
What about creating links to the files/directories that have the MVC? That is better than making copies.

What's the best way to integrate a Django and Rails app sharing the same MySQL datastore?

I'm going to be collaborating with a Python developer on a web
application. I'm going to be building a part of it in Ruby and he is
going to build another part of it using Django. I don't know much about
Django.
My plan for integrating the two parts is to simply map a certain URL
path prefix (say, any request that begins with /services) to the Python
code, while leaving Rails to process other requests.
The Python and Ruby parts of the app will share and make updates to the
same MySQL datastore.
My questions:
What do people think generally of this sort of integration strategy?
Is there a better alternative (short of writing it all in one language)?
What's the best way to share sensitive session data (i.e. a logged in
user's id) across the two parts of the app?
As I see it you can't use Django's auth, you can't use Django's ORM, you can't use Django's admin, you can't use Django's sessions - all you are left with is URL mapping to views and the template system. I'd not use Django, but a simpler Python framework. Time your Python programmer expanded his world...
One possible way that should be pretty clean is to decide which one of the apps is the "main" one and have the other one communicate with it over a well-defined API, rather than directly interacting with the underlying database.
If you're doing it right, you're already building your Rails application with a RESTful API. The Django app could act as a REST client to it.
I'm sure it could work the other way around too (with the rest-client gem, for instance).
That way, things like validations and other core business logic are enforced in one place, rather than two.
A project, product, whatever you call it, needs a leader.
This is the first proof that you don't have one. Someone should decide either you're doing ruby or python. I prefer ruby myself, but I understand those who prefer python.
I think starting a product asking yourself those kind of questions is a BAD start.
If your colleague only knows prototype, and you only know JQuery, are you going to mix the technologies too? Same for DB? And for testing frameworks?
This is a never ending arguing subject. One should decide, IMHO, if you want so;ething good to happen. I work with a lot of teams, as a consultant, Agile teams, very mature teams for some of them, and that's the kind of stuff they avoid at all cost.
Except if one of you is going to work on some specific part of the project, which REALLY needs one or other of the technologies, but still think the other one is best for the rest of the application.
I think, for example, at a batch computing. You have ALL your web app in ror or django, and you have a script, called by CRON or whatever, computing huge amounts of data outside the web app, filling a DB or whatever.
My2Cts.

What is the best strategy to combine IntrAnet and Web-exposed website?

I was wondering if somebody has some insight on this issue.
A little background:
We've been using Rails to migrate from an old dBase and Visual Basic based system
to build internal company IntrAnet that does things like label printing,
invetory control, shipping, etc - basically an ERP
The Dilemma
Right now we need to replace an old customer-facing website that was done in Java, that
would connect to our internal system for our clients to use. We want to be able to pull information like inventory, order placement, account statements from our internal system and expose it to site live. The reason is that we take orders on the website, through fax & phone and sometimes we have walk-ins. So sometimes (very rarely thou) even a short delay in inventory update on our old Java site causes us to put an order on backorder, because we sell the same item to 2 customers within half an hour. It's usually fixed within one day but we want to avoid this in the future.
Actual Question
Does anyone have any suggestion on how to accomplish this in a better
way?
Here are three options that I see:
a) Build a separate Rails app on a web server, that will connect to the same DB that our internal app connects to.
+++ Pluses:Live data - same thing that our internal apps see, i.e. orders are created in real time, inventory is depleted right away
--- Minuses: Potential security risk, duplication of code - i.e. I need to duplicate all the controllers, models, views, etc. that deal with orders.
b) Build a separate Rails app on a web server, that will connect to a different DB from our internal app.
+++ Pluses: Less security exposure.
--- Minuses:Extra effort to sync web DB and internal DB (or using a web service like REST-API), extra code to handle inventory depletion and order # creation, duplication of code - i.e. I need to duplicate all the controllers, models, views, etc. that deal with orders.
c) Expose internal app to the web
+++ Pluses: all the problems from above eliminated. This is much "DRY"er method.
--- Minuses: A lot more security headaches. More complicated login systems - one for web & one for internal users using LDAP.
So any thoughts? Anyone had similar problem to solve? Please keep in mind that our company has limited resources - namely one developer that is dedicated to this. So this has to be one of those "right" and "smart" solutions, not "throw money/people/resources at this" solutions.
Thank you.
I would probably create separate controllers for the public site and use ActiveResource to pull data from you internal application. Take a look at
http://blog.rubybestpractices.com/posts/gregory/rails_modularity_1.html
http://api.rubyonrails.org/classes/ActiveResource/Base.html
Edit - fixed link and added api link
I would go for a. You should be able to create the controllers so that they are re-usable.
Internal users are as likely to duplicate data as external users.
It's likely that a public UI and an internal, for-the-staff, UI will need to be different. The data needs to be consistent so I would put quite a bit of effort into ensuring that there is exactly one, definitive database. So: one database two UIs?
Have a "service" layer that both UIs can use. If this was Java I would be pretty confident of getting the services done quickly. I wonder how easy it is in Ruby/Rails.
The best outcome would be that your existing Customer Java UI can be adapted to use the Rails service layer.
Assuming you trust your programmers to not accidentally expose things in the wrong place, the 'right' solution seems to me to have a single application, but two different sets of controllers and views, one for internal use, and one for public-facing. This will give you djna's idea of one database, two UIs.
As you say having two separate databases is going to involve a lot of duplication, as well as the problem of replication.
It doesn't make sense to me to have two totally separate apps using the same database; the ActiveRecord part of a Rails app is an abstraction of the database in Ruby code, therefore having two abstractions for a single database seems a bit wrong.
You can also then have common business rules in your models, to avoid code duplication across the two versions of the site.
If you don't completely trust your programmers, then Mike's ActiveResource approach is pretty good - it would make it a lot harder to expose things by accident (although ActiveResource is a lot less flexible and feature rich than ActiveRecord)
What version of Rails are you using? Since version 2.3 Rails Engines is included, this allows to share common code (models/views/controllers) in a Rails plugin.
See the Railscast for a short introduction.
I use it too. I have developed three applications for different clients, but with all the shared code in a plugin.

Resources