Saturday, October 22, 2011

Rails is Not Your Application

Background: The Beginnings of My Obsession with Application Architecture and Domain Modelling

Last year I was involved in my most complex Ruby on Rails application to date that is now 23K lines of model code, 14K lines of controller code, and 4.5K lines of lib code. You get the point, let's now worry about the view code. It was during this project that I observed the pain of working within the bounds of how we typically build Rails applications. Did I mention it was slow to develop and test? During that contract and ever since, I have been obsessing about application architecture and domain modelling.

Establish an Application Interface with a Service Layer

During the time I was working on said application, I introduced the concept of Services (in the early stages I called them managers). Although a lot of domain logic was pushed into the models, there was too much application logic in the controllers. Services, co-ordinating domain models, allowed me to extract that application logic to really keep the controllers thin. I'm not sure exactly sure what prompted me to start using Service objects, but after the fact I found references to them in Martin Fowler's Patterns of Enterprise Application Architecture (P of EAA). Other frameworks such as Grails also use Services, it even has a generator for them. Services resolves the discussion (started here) on where to trigger email notifications. Add them to your Services.

In P of EAA, Randy Stafford defines the Service Layer as:

"Defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation."

And in a way, this definition helped me recognize another frustration I was having with how I (and most of the Rails community) was developing with Rails. There was no explicit application. Or rather, it was hard to define what the application was and hard to know how to interact with it. The application had no interface. My application was a ball of ActiveRecord objects.

Lots of Activity in the Rails Community Regarding Domain Modelling

I haven't been the only one thinking about application architecture and domain modelling. I'm not a unique snowflake. Others in our community have too: Mike Dietz from ThoughtWorks introduce me to DCI at RailsConf 2011Andrzej Krzywda has been blogging about it before that, and Jim Gay has recently been blogging about it on this side of the pond. On another tact, Corey Haines has been been selling fast tests over the last few months. Hidden in that sales pitch of course, is a way to extract domain logic. Talking of extracting domain logic, Steve Klabnick has illustrated some practical examples.

These guys have kept me busy! I've been quietly researching this topic for over a year now. You can check out some of my tags on Delicious:

Extracting the Application from the Framework

Ok, time to finish up this post. All of the efforts describe above have been with the purpose of managing the application and domain logic in the software we build. It benefits us with faster tests and code that clearly communicates it's intent. And although the Service Layer was helping me define an interface to my application, I was only using them when my controllers methods/actions were getting heavy with application logic. Then last night, I watched the latest release of Clean Code from Uncle Bob that highlights the need to extract your application from the framework you use (he's been teasing me for a while on this topic). With my previous experience with Services, and my interest in DCI, Uncle Bob's guidance was the piece I was missing.

After taking his example pseudo code, and turning it into some Ruby/Rails example (more like snippet) I gleefully tweeted:

"Rails is not your application. It might be your views and data source, but it's not your application. Put your app in a Gem or under lib/."

I really like this approach a lot, the ability to test your application outside of the Rails stack is huge, and viewing Rails as a method to deliver my application will change the way I write code. Anyway here is the code that triggered the Tweet (see below). It's not polished, it doesn't execute, it's not 100% right, but boy it's got me thinking. It uses Services to represent Use Cases of the application, and roles containing domain logic that is mixed in contextually, extracted into a Gem, delivered via Rails. If you not a fan of the Gem idea, keep it name spaced under your lib directory.

Update: A clarification on putting your application in lib. I certainly don't mean to put it directly in lib. Name space it, lib/your_application; e.g. lib/pay_roll.

Now that I have let the code out of the bag, expect some more posts on this topic in the future where I work through and describe this code (and related ideas) in more detail.

Written by .

Monday, October 17, 2011

References and tools for Memory Consumption in Rails

It's not often that I need these, but when there's a Memory Consumption issue in a Rails application, these references and tools definitely come in handy:

Rails 3 References and Tools

Some Older References and Tools

Saturday, October 15, 2011

Recent Launch: Media Experts on Refinery CMS

Media Experts is a top Canadian media planning and buying agency. During the summer, I was tasked with the first iteration of their website, integrating it with Refinery CMS (thanks Dynamo!). One of the joys of using Refinery, is the ease of extending it with engines to support custom content types. For example the experts page seen below contained structured, repetitive data that was not suited for a page tree hierarchy:

Media Experts - People

By generating a custom engine, I was able to easily integrate this structured data into the website, without any impact on the original design or the website's navigation. You can view how the individual experts are edited in the screen shot below:


Please checkout the Media Experts' website and view additional screenshots below:

Home Page

Media Experts Home

Portfolio Index

Media Experts Portfolio

Sunday, October 9, 2011

Yellow Bird Project Spree Upgrade

During the spring, Dynamo asked me to upgrade the Yellow Bird Project to the latest version of Spree (at the time this was v0.50.2). The challenge for this project was managing the upgrade from a forked version of Spree, pre v0.9.0 back in 2009. One tool that was really useful was using Max OS X's FileMerge to compare database schemas, allowing me to determine what the new schema would and determine any naming conflicts with custom tables added previously.

Filemerge schema

The upgrade resulted in an application that can now be easily upgraded to future version of Spree and runs on a more stable, scalable platform thanks to Heroku.

The Yellow Bird Project is pretty cool - they work with a range of indie rock musicians to create some neat t-shirts that then benefit a charity chosen by the musicians themselves. So put away that ugly university hoodie and go get yourself some cool threads.

Yellow bird project home

Saturday, October 1, 2011

Recent Launch: de Gaspé Beaubien Foundation

OK, hardly a recent launch, de Gaspé Beaubien Foundation was actually launched in April, but I'm a wee bit behind in posting some of the neat projects I have worked on this year. I'm determine to get this resolved over the next couple of weeks.

de Gaspé Beaubien Foundation's website provides a platform to communicate the families contribution to their communities and the broader society. I worked with the great team at Dynamo on this one: Bob Beck, creative director was responsible for brand identity and video direction, Jenna Holcombe site design, and I was responsible for front-end development and CMS integration.

This is the first project I have used RefineryCMS, a Ruby on Rails-based Content Management System. While I have been a big fan of Radiant CMS, I like RefineryCMS for it's polish integrated interface. It worked great for this project, but I would use Radiant when a project has more complex requirements. The front-end was developed using HTML5 and CSS3. CSS was generated using Compass and Sass. Compass' CSS3 helpers are a real help abstracting away the mess of vendor extensions, and the CSS3 PIE integration giving older version of IE CSS3 capabilities is invaluable. All video is presented using HTML5, with a Flash fallback, all handled seamlessly by JW Player.

Check out the screenshots below and please visit the site to find out the great work de Gaspé Beaubien Foundation is doing.

de Gaspé Beaubien Foundation

de Gaspé Beaubien Foundation

de Gaspé Beaubien Foundation

de Gaspé Beaubien Foundation

Please note this blog is no longer maintained. Please visit CivilCode Inc - Custom Software Development.