Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run a customized version of a Rails application

Here's our basic requirements:

  • We have a base Rails application, which is being actively maintained.
  • We want to offer a customized version of this app, given that:
    • servers must reside in our customer's premise and run on a different domain.
    • there's a specific logging instrumentation for their own monitoring in the datacenter.

To do that, I can see several options to achieve that goal:

  • Git branch
  • Rails::Engine
  • Rails::Application

The most obvious answer would be Git branch, for full flexibility.

However I'm not sure if it's a good idea, because the code base is largely shared and the mainline has a lot more activities - catching up with rebase / merge could be just extra hassle.

We want to decouple the original and the customized versions as far as possible. In other words, we want to have as less often conflicts as possible between the original and the customized.

Rails::Engine or Rails::Application seemed like a close idea (I'm not familiar with Rails Engines), but I don't understand how to have OurApp::Application and OurCustomizedApp::Application in one place and switch between them globally and dynamically.

Probably it would be nice to have:

  • custom initializers, controllers and views in a separate directory to override (or patch) the original
  • ability to specify which app (the original or the customized) to boot by an environment variable like RAILS_APP
  • separate config files, like so: config/database.yml to be config/customer1/database.yml
  • ability to use the same deploy.rb for capistrano (probably with config/servers.yml and config/customer1/servers.yml to define roles and IPs?)

Is there practices / conventions for our requirements? Any advice?

Our apps run on Ruby 1.9.2 + Rails 3.0.3.

UPDATE

We started it as a Git branch. We created a rake task to generate a file at config/branch that includes text like "master" or "customized", and application.rb reads it upon bootstrap. Configs like database.yml or servers.yml now live in config/mainline/ or config/customized/, and application.rb handles them accordingly.

config.paths.config.database = "config/#{branch}/database.yml"

Not perfect, but good enough for now. I'll update when we find a better way to do this.

like image 901
kenn Avatar asked Jan 15 '11 21:01

kenn


People also ask

How do I run a Rails application?

Go to your browser and open http://localhost:3000, you will see a basic Rails app running. You can also use the alias "s" to start the server: bin/rails s . The server can be run on a different port using the -p option. The default development environment can be changed using -e .

What is Rails application config?

In general, the work of configuring Rails means configuring the components of Rails, as well as configuring Rails itself. The configuration file config/application. rb and environment-specific configuration files (such as config/environments/production.


1 Answers

I think the best approach is to do this the old fashioned way.

First, add a singleton class to your project (in /lib) called something like Affiliate. This class should supply default implementations (whatever you want your base application to use) for any parts of the application that can be customized. At this point, your application functions the same, but has hooks to allow customization.

At your customer's site, deploy the same source code (shipped as a gem, maybe?), but also deploy a Rails plugin that overrides Affiliate so its singleton instance method returns a custom subclass that supplies customer-specific information or behaviours.

Edited to add: The risk with this approach is that developers inadvertantly break things because they only test their changes against the default affiliate. You should use automated testing and continuous integration to catch this.

like image 145
Michael Melanson Avatar answered Sep 20 '22 03:09

Michael Melanson