Decoupling from Rails

Here is a great talk called Decoupling from Rails by the late Jim Weirich.

This talk is most famous for being taken up by David Heinemeier Hansson as an example of “test induced design damage” during his Is TDD Dead? conversation series with Kent Beck and Martin Fowler. Putting that debate aside, though, here are some things this talk got me to understand more deeply or start thinking about:

Differentiating between “framework” code that we don’t own, and “application” code that we do. It’s interesting to think about defining clear boundaries between these two types of code, and about decoupling them as much as possible. (It’s worth thinking about even if you don’t end up doing it in the end!).

Many people encourage writing wrappers around external APIs we use in our application. It’s considered good practice to write and interact with a PaymentGateway wrapper we do own, which wraps a Braintree gem which we don’t own, rather than interacting directly with Braintree throughout the application. This is the same concept, except applied to Rails.

Injecting Rails objects as a dependency into plain old ruby objects. Rails is still the “context” in which other things are done, but you can dynamically swap in other contexts that respond to the same methods the Rails context does:

class EmployeesController < ApplicationController
  def create
    CreateRunner.new(self)
  end
end

class CreateRunner
  attr_reader :context

  def initialize(context)
    @context = context
  end

  def do_something
    context.do_something
  end
end

Wrapping ActiveRecord models up in a business logic layer using simple delegator. This is something I’ve heard a lot about but haven’t personally started doing yet. It was great to see a live-coding example of making it work. (At around minute 56 of the talk).

Some nice text-editing moments. Jim had something automatic set up for extracting variables into methods.

I hope you enjoy the talk as much as I did!