Projects using Ruby on Rails often lack strong distinctions in two main areas:
- The model/record conflation: Seeing “models” as strictly DB-backed resources.
- The view/template conflation: failing to draw a line between view objects and HTML templates.
The conflations are encouraged by Rails’ design decisions. When choosing which enterprise design patterns to translate into code, the Rails developers chose Active Record (a relatively thin, one-to-one take on the ORM idea), and Template View.
I am not faulting them for this decision. These were both thoroughly pragmatic decisions which mapped well to the kind of applications that Rails was aimed at. By encoding these opinions into the framework and covering them with a sweet coating of convention-over-configuration, Rails saved thousands of projects from pattern analysis paralysis.
But now Rails applications are maturing, and a lot of developers are starting to realize that these patterns may not scale so well to more and more complex applications. When figuring out how to move forward, we could do much worse than to consult the same book that laid the blueprints for Rails’ architecture, Patterns of Enterprise Application Architecture.
Here’s Martin Fowler on Domain Models:
An OO domain model will often look similar to a database model, yet it will still have a lot of differences. A Domain Model mingles data and process, has multivalued attributes and a complex web of associations, and uses inheritance.
As a result I see two styles of Domain Model in the field. A simple Domain Model looks very much like the database design with mostly one domain object for each database table. A rich Domain Model can look different from the database design, with inheritance, strategies, and other [Gang of Four] patterns, and complex webs of interconnected objects. A rich Domain Model is better for more complex logic, but is harder to map to the database. A simple Domain Model can use Active Record, whereas a rich Domain Model requires Data Mapper.
Note that Fowler is referring to the Active Record and Data Mapper design patterns, not to the Ruby libraries those patterns inspired. There is a correspondence, though: the DataMapper library, like the pattern it is based on, puts a higher value on decoupling the domain model from the database schema.
Now on to views. Here’s Fowler talking about Two Step Views, an alternative to the Template View pattern:
You may… want to want to make global changes to the appearance of the site easily, but common approaches using Template View or Transform View make this difficult because presentation decisions are often duplicated across multiple pages or transform modules. A global change can force you to change several files.
Two Step View deals with this problem by splitting the transformation into two stages. The first transforms the model data into a logical presentation without any special formatting; the second converts that logical presentation with the actual formatting needed.
I do a lot of two-step view processing in my projects. I haven’t had a chance to take a close look at, but I think this process is also what Jeff Casimir is aiming at with Draper, and I support and applaud his efforts.
And that’s all I had to say about that… I just wanted to post those quotes in case anyone else found them noteworthy.