Best practice for structuring a 'large' Rails app Best practice for structuring a 'large' Rails app apache apache

Best practice for structuring a 'large' Rails app


I believe the benefits of isolating your concerns into separate apps outweigh the costs. I would probably start off with just 2 apps (one for the main site and superadmin, one for the client sites and admins), accessing the same database, but you could do 4.

The downside is you don't really have isolation since all your apps are tied to one database. You will eventually run into scaling problems with your database, but starting off simple with one database will get you launched. One strategy for scaling later would be to add a slave db that the client site and main site apps use, while the admin apps use the master db. This along with a TON of caching will get you pretty far.

There is nothing wrong with having multiple rails apps access one db, however you will need a way to share common code across your apps. Your models for the most part. I've done this before by tossing all my models in a plugin that I share as a sub-module in git or as an external in svn. Having separate apps will make each app smaller and easier to maintain.

However, where do you keep your migrations? Where do you test your models? I would opt for the superadmin app. Also, you make a change to a model or the schema, and now you have to check 2-4 apps and make sure they still work!

Better isolation, separate db's and inter-app communication through web APIs (SOA) and you don't have to worry about that. SOA I think is the way to go after a certain point, but SOA might be premature when you first start out.

At any rate, having separate apps sets you up for SOA but you don't have to jump beyond a single db to start.


I would bundle this all into the same app because you won't be duplicating the classes (models, plugins, etc.) across all the apps. Also: running 4 apps means that you'll have 4 processes all consuming memory due to the 4 separate Rails stacks they have loaded.

Compiling it into one application eliminates this issue. For the issue between the sales site and the users site having to have different roots that can be solved, as mentioned earlier, by subdomain_fu. Let me expand with some sample code from an application I have:

map.with_options :conditions => {:subdomain => 'logs'} do |admin|  admin.resources :channels do |channel|    channel.resources :logs  end  map.root :channels  map.connect ':id', :controller => "channels", :action => "show"end

As we see here, the :conditions for the with_options method sets :subdomain to be logs which means that anything coming in to logs.mysite.com will fufill these conditions and therefore be routed this way.

Now further on in this routing file I have everything else wrapped up in a similar block:

map.with_options :conditions => {:subdomain => nil} do |admin|  # shebang!end

Everything going to mysite.com will go to these routes.

Lastly, compiling it all into one mega-super-hyper-app will eliminate the database-sharing issues.


The biggest issue I see with separating into several apps is that you lose flexibility. What happens if, in the future, a previously administrative task (eg. uploading a type of file) becomes a "user task"? You would have to be moving code from one application to the other.

I'd keep everything on single application - and use roles for filtering what each user can see and do. It might be a bit more difficult at the begining, but it pays up in the near future.

Have a look at authorization frameworks, such as declarative_authorization or cancan.