Modularising and DRYing up code

Hi there,

My company (and product) Spike@School (www.spikeatschool.co.nz) is basically a CMS for schools. It allows you to add pages, links, blah, and more complicated things like podcasts and staff profiles to the site. We developed it around a central core called component_instances. It's basically an ordered tree structure (which we're aching to convert to a nested set, but that's another story). The tree is polymorphic so you can add a Page node anywhere in the tree (for example).

That's all well and good, but as time goes on, schools ask for these things called e-Portfolios which are basically mashups of things like pages, lists of links, embedded content, la de dah. The problem is, the interface where a student can add new pages, links etc... to their e-portfolio is slightly different to the interface that a teacher would use to add pages to the general site tree. We also have these things called Learning Caves which are basically private areas where students and teachers can collaborate. Again, they're using pages, links etc.. and again we're duplicating some code. In the Learning Caves example we are using the same models which is good, we're also using some of the same view and controller code for the teachers view (as the input dialogues are basically the same for them). We did however need to copy the code and modify it ever so slightly for the students end (they have a different template, permissions structure etc...). This leads me to the question:

What is the best way to abstract these things to a modular format?

I've thought of using plugins, but they don't seem to go to the controller level. I've also tried abstracting the controller code to the lib directory and including this in the controllers where necessary (with lots of conditional workaround for certain differences in each use case for the module). We call the common view code as a partial from a messy location (usually the back-end view area since that would usually have been written first). Anyway, the point is, I feel like i'm flailing around trying to fit this round peg into a square Rails hole. Has anyone else come by this problem with larger projects? Are there plugins around to handle this?

I appreciate that this is quite an abstract problem and that the only answer might be a hard to swallow one, but we'll see :slight_smile:

Cheers,

Brendon