views:

37

answers:

1

I'd like to develop a number of non-trivial Rails applications which all implement a core set of functionality but each have certain particular customizations, extensions, and aesthetic differences. How can I pull the core functionality (models, controllers, helpers, support classes, tests) common to all these systems out in such a way that updating the core will benefit every application based upon it?

I've seen Rails Engines but they seem to be too detached, almost too abstracted to be built upon. I can seem them being useful for adding one component to an existing app, for example bolting on a blog engine to your existing e-commerce site. Since engines seem to be mostly self contained, it seems difficult and inconvenient to override their functionality and views while keeping DRY.

I've also considered abstracting the code into a gem, but this seems a little odd. Do I make the gem depend on the Rails gems, and the define models & controllers inside it, and then subclass them in my various applications? Or do I define many modules inside the gem that I include in the different spots inside my various applications? How do I test the gem and then test the set of customizations and overridden functionality on top of it? I'm also concerned with how I'll develop the gem and the Rails apps in tandem, can I vendor a git repository of the gem into the app and push from that so I don't have to build a new gem every iteration? Also, are there private gem hosts/can I set my own gem source up?

Also, any general suggestions for this kind of undertaking? Abstraction paradigms to adhere to? Required reading? Comments from the wise who have done this before? Thanks!

+1  A: 

Never did such a thing, but I guess that a Rails plugin would be the right place for it:

http://guides.rubyonrails.org/plugins.html#models

http://guides.rubyonrails.org/plugins.html#controllers

http://guides.rubyonrails.org/plugins.html#helpers

And you can create a gem out of it afterwards:

http://guides.rubyonrails.org/plugins.html#plugingems

Mladen Jablanović
A plugin would indeed be the simplest way...
severin
Can you try and explain how I would reopen (or subclass if reopening isn't possible) classes defined in my plugin inside the application? My main issue is sharing code between both the plugin and the application, where say a model's normal behaviour is defined in the plugin but the application overrides just a few methods. If I define the model in application, Rails looks there first, finds the class it was looking for, and the missing constant becomes defined. Rails never looks in the plugin, which means none of my core functionality comes through.
hornairs