# Large RoR systems design and implementation

**URL:** <https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388>\
**Category:** Rails\
**Created:** [February 4, 2009, 4:00am UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388 "2009-02-04T04:00:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![sbrocher](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/49beb7/32.png) [@sbrocher](https://www.ruby-forum.com/u/sbrocher)\
**Post date:** [February 4, 2009, 4:00am UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388/1 "2009-02-04T04:00:33Z")

</div>

Hi,

I’ve implemented a few big RoR apps. I do have some good experience  
building large systems in many different languages and platforms but I  
don’t consider myself a RoR guru, so I’d like you experts comment on  
my thoughts.

I’d like to divide a large system (app) into several functional, high-  
level sub-systems. These are higher level than rails Models, and  
provide APIs that implement business logic around functional groups.  
Examples of these are billing manager, security manager (accounts,  
privileges, roles, etc), inventory manager, manufacturing manager, and  
such (of course, these are just examples, but you get the point).

These high-level sub-systems may be implemented as servers (think  
SOAP / REST / XML-RPC / …), or just plain Ruby classes. Some of  
these sub-systems implement integrations with other systems, for  
example, a credit card gateway, an accounting system, Fedex, you name  
it. Some of the sub-systems may be just proxies to a system  
implemented on some other technology.

The user interface (views) would not have access to any of the Models.  
They just present and / or grab data that is prepared for them /  
pushed back to the controllers as local variables / arrays / hash  
tables that don’t reflect an actual Model.

The controllers do not have access to Models either. Instead, they  
call methods from the high-level functional sub-system APIs.

The Models implement lower-level business logic related to how to the  
information is stored and retrieved from the database, the pertinent  
validations, associations, etc. but do not implement high-level  
business logic such as “how do I bill Joe for a specific event that  
results in the combination of many other parameters and variables that  
at the end come from diverse fields on many different tables on the  
underlying database structure”.

The high-level sub-systems all share the same database and therefore  
same data model and only communicate with each other via their APIs,  
and can access all Models directly.

In other words, this would work more or less as a new layer in between  
the MVC pattern:

view \<-\> controller \<-\> high-level sub-system \<-\> models \<-\> database

The idea is to build the app in a more robust / less coupled way where  
I can exchange parts of the app by different technologies and other  
applications in the future without having to recode a bunch of things.  
For example, the security subsystem could one day be replaced by an  
AAA server and then the subsystem would be re-implemented to call the  
AAA server (to replace its own original implementation), however the  
rest of the app would continue to use the same API calls to the  
security subsystem and so the change is isolated from the rest of the  
app.

The problem with this is, I’d loose many of the RoR goodness, such as  
form helpers, easy models validation thrown back to the interface,  
etc.

Am I missing some Ruby language construct or RoR framework construct  
that would enable me to implement this kind of design on an easier  
manner? Should I instead be thinking of many RoR applications somehow  
talking to each other?

I really like RoR but I’m starting to find myself on a tough situation  
dealing with evolving mid-to-large systems (think 50+ database tables  
and 8+ sub-systems). I need to come up with a pattern that would force  
me to implement and design code that works and is maintainable on a  
long-term vision, however I’m not sure if this is because I don’t know  
the 100% of what the language and framework has to offer, or if I am  
just using it the wrong way (or both? :-).

Comments?

Thanks,  
Seb

---

<div class="post-metadata">

**Author:** ![sbrocher](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/49beb7/32.png) [@sbrocher](https://www.ruby-forum.com/u/sbrocher)\
**Post date:** [February 4, 2009, 4:34am UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388/2 "2009-02-04T04:34:28Z")

</div>

Datamapper.

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)

---

<div class="post-metadata">

**Author:** ![sbrocher](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/49beb7/32.png) [@sbrocher](https://www.ruby-forum.com/u/sbrocher)\
**Post date:** [February 4, 2009, 7:29pm UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388/3 "2009-02-04T19:29:10Z")

</div>

Hi Julian,

Thanks for your answer. I’ve seen Datamapper before. However, the way  
I understand it, Datamapper is pretty much just a replacement for  
ActiveRecord, so I don’t see how it would add the extra layer of  
abstraction I’m searching for… Did I miss something here?

Thanks  
Seb

---

<div class="post-metadata">

**Author:** ![sbrocher](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/49beb7/32.png) [@sbrocher](https://www.ruby-forum.com/u/sbrocher)\
**Post date:** [February 4, 2009, 7:46pm UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388/4 "2009-02-04T19:46:15Z")

</div>

Hello Seb,

An approach that I have used is to place the higher level business  
logic in model objects that do not inherit from ActiveRecord. In  
the way I think about larger systems, the higher level business  
logic is still part of the model. The model is not limited to  
managing the persistence of state. I don’t have a formal way of  
organizing these subsystem model objects as I haven’t tackled any  
projects that sound as extensive as what you are working on.

HTH  
Kim

On Feb 4, 2009, at 11:28 AM, sbrocher wrote:

> > > high-  
> > > example, a credit card gateway, an accounting system, Fedex, you  
> > > The controllers do not have access to Models either. Instead, they  
> > > underlying database structure".  
> > > database  
> > > rest of the app would continue to use the same API calls to the  
> > > that would enable me to implement this kind of design on an easier  
> > > me to implement and design code that works and is maintainable on a
> > 
> > - Show quoted text -

–  
Kim S. - principal, Shrier and Deihl - [mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Remote Unix Network Admin, Security, Internet Software Development  
Tinker Internet Services - Superior FreeBSD-based Web Hosting  
[http://www.tinker.com/](http://www.tinker.com/)

---

<div class="post-metadata">

**Author:** ![sbrocher](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/49beb7/32.png) [@sbrocher](https://www.ruby-forum.com/u/sbrocher)\
**Post date:** [February 4, 2009, 7:49pm UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388/5 "2009-02-04T19:49:48Z")

</div>

A good starting point is read Eric Evan’s “Domain Driven Design”, you  
will probably learn a lot about how to organize big systems in any  
language. The book is easy to read and has examples in Java.

- 

Maurício Linhares  
[http://alinhavado.wordpress.com/](http://alinhavado.wordpress.com/) (pt-br) | [http://blog.codevader.com/](http://blog.codevader.com/)  
(en)

---

<div class="post-metadata">

**Author:** ![sbrocher](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/49beb7/32.png) [@sbrocher](https://www.ruby-forum.com/u/sbrocher)\
**Post date:** [February 5, 2009, 1:35am UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388/6 "2009-02-05T01:35:05Z")

</div>

The reasons you explained you wanted the layer made me think you only  
needed datamapper. Be simpler rather than complex. Explain again why  
you need the layer, please? Remember YAGNI.

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)

---

<div class="post-metadata">

**Author:** ![sbrocher](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/49beb7/32.png) [@sbrocher](https://www.ruby-forum.com/u/sbrocher)\
**Post date:** [February 5, 2009, 10:07am UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388/7 "2009-02-05T10:07:20Z")

</div>

Hi Julian,

No worries. I’m just after the basic high-level design concept where  
you first break the (large) problem into several subsystems (i.e.:  
divide and conquer). Then define APIs for each subsystem. Then  
implement each subsystem. Test each system separately. Integrate. Test  
whole system. Also known as the “V” model at another level of  
abstraction.

This has many benefits and is a proven technique to design large  
systems. It reduces coupling and makes it easier to integrate with  
other systems in the future, work with large teams, write more  
maintainable code, etc. It also enables you to break down the app onto  
different servers in the future as needed, by adding something like  
SOAP, REST or XML-RPC in between those APIs.

For example, if a part of the app deals with inventory management, it  
will have it’s own API. Then if one day I decide to buy an inventory  
management system from a vendor that has its own API and similar  
features, all I have to do is write a connector (proxy) and place it  
inside my app, replacing the inventory management subsystem  
implementation by the proxy that communicates back and forth with the  
newly acquired system, but without needing to change any of my  
interface code, other business logic code, etc.

Seb

---

<div class="post-metadata">

**Author:** ![sbrocher](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/49beb7/32.png) [@sbrocher](https://www.ruby-forum.com/u/sbrocher)\
**Post date:** [February 5, 2009, 4:28pm UTC](https://www.ruby-forum.com/t/large-ror-systems-design-and-implementation/159388/8 "2009-02-05T16:28:38Z")

</div>

You may be better off using the new engines or merb slices

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)
