The Consulting CTO

On Returning to Rails

Returning to Rails after about 3 years, I’d like to share some observations. I want to state at the outset that Rails is an excellent fit for the project, and I have no regrets about selecting it. It’s just been a while since I’ve slipped on this particular pair of shoes, and they don’t fit quite the way I remember.

I’ve been using Rails for over 12 years (and Ruby a bit longer than that). I’ve built and worked with a range of Rails applications from small middleware applications all the way up to high-traffic, multi-tenant systems like Big Cartel. However, over the past few years, my work has steadily moved away from building web applications and more into architecture and “pure” backend work (including working with technologies like Terraform and Lambda). I’ve also transitioned to primarily working in Clojure and ClojureScript (which will become readily apparent from my comments below).

The first thing that caught me off-guard is how tightly coupled Rails views are to ActiveRecord and, by extension, to the database schema. Over the past few years, I’ve gotten used to working with a decoupled front- and backend, allowing me to delay decisions such as how I’m going to represent a domain model when I persist the data (or even how I’m going to persist the data). Using ActiveRecord forced me to spend a lot more time early on thinking through the data model, even before I had a firm grasp on the domain.

Working with ActiveRecord also constrained what I could do in the views given the project timeline. (Naked objects, anyone?) While this was not necessarily a bad thing in the context of my current project, the downside is that it is difficult to get the user into working software as quickly (though I have some thoughts on how to facilitate that in the future).

Coming from Clojure, the fact that ActiveRecord hides side-effects behind a DSL just feels wrong to me now. Accessing an attribute while rendering a view should not trigger a database query. I understand how this seems to be conceptually simpler for developers, but over the long run, I believe it is much cleaner to keep I/O decoupled from view rendering and business logic. This is a great example of what Rich was talking about in Simple Made Easy.

Having to relearn the various Rails DSLs has also been occasionally frustrating. I know SQL well enough by now that there are times when the ActiveRecord DSL gets in my way. I know what I want to accomplish, but I have found myself having to dig through documentation and Stack Overflow to figure out how to make the DSL do what I want. And, naturally, there are times when what I want to do is simply not possible.

I’ve tried to stick as closely to omakase Rails for this project, but Rails’s standard JavaScript handling is simply not usable for me anymore. Luckily, Basecamp has recently shared their JavaScript framework, Stimulus, and I have to admit, it’s quite elegant. I’m not ready to give up React, but I will certainly use Stimulus again (with or without Rails). It does feel odd to use the DOM as a data store, though.

At the end of the day, I chose Rails for this project for three primary reasons. First, it saved me a lot of peripheral decisions that don’t provide added value to my client (e.g., choice of logger, asset pipeline, session handling, etc.). Second, my client will have an easier time finding developers to maintain the system over its life. Finally, the affordances Rails provides also act as constraints, enabling me to focus on the project’s value to the client rather than my own architectural predilections. The application I’ve been building is, at its core, a form-driven database, and that’s one of Rails’s sweet spots.

Get the latest posts from The Consulting CTO