What Comes After MVC «

Code: ,

Rails apps start out quickly and beautifully, but after a year features are a struggle, tests are slow, developers are grinding, and stakeholders are unhappy. “Skinny controllers and fat models” hasn’t worked, and “use service objects!” is awfully vague.

This talk explains how to compact the “big ball of mud” at the heart of your app into a bedrock of reliable code. It gives the steps to incrementally refactor models into a functional core and gives explicit rules for how to write light, reliable tests.

I’m excited to speak at RailsConf 2015 today about What Comes After MVC. I had a lot of fun with the talk, including making a trailer to respond to DHH’s keynote rebranding “monoliths”:

And here’s the official video:

If you’d like a copy of the slides with comprehensive speaker notes and links to all the tools and examples, fill in this form. I had a lot more info I had to cut for time, so I’ll send that as I finish it.

What Comes After MVC

Get the slides with comprehensive speaker notes by signing up. I’ll also send an email every week or two with stuff I had to cut for time like code examples (especially of tests), a detailed how-to walkthrough, and connections to related topics in writing reliable code. Unsubscribe when you’re not interested. I have cleaned up enough servers hacked by spammers that I’ll never sell or spam your email address.

If you’re here at RailsConf today, please come talk to me. This is not reality TV, I am here to make friends. I love talking about this stuff. And if you’re reading this later, please feel free to email me, I love talking about this stuff and I’m ph at this domain.


  1. Great talk. Brain exploding now. Signed, maintains models approaching 3000 loc (with includes).

  2. For clarity I would’ve used an ActiveRecord example since the talk is intended to enlighten a Rails audience. A part from that great talk !

    My take on the “what/how to refactor” conversation going on since 4 or 5 years is the fundamental unbalance in controllers between the “displaying” methods (index show new) and those which mutate models and deal with side effects (create & update). Most of the bad cholesterol pushed in AR Models to comply with the skinny controller moto comes from there. Interaction with users is a lot more complex than showing a fixed state : it has many contextual (admin/user), security (params, validation), and side effect (callback, associations, sending emails) issues…

    Having a specific and conventional way to deal with interactions is anything but overkill. I’m using Virtus + ActiveModel in a little gem of mine as an adapter to remove all or most of the callback, association & validation cruft out of AR model so they’re as close as possible to an entity.

  3. I would have loved to use an ActiveRecord model but I didn’t have one I could use – dang NDAs on client code! I went back and forth about whether to write one from scratch and ultimately decided it was more useful to show messy, real, personal code.

    Thanks for sharing your thoughts, I’m going to enjoy reading the paramount code. :)

  4. Loved your talk. I loved the side-effects/mutable quadrant. It has really helped with how to think about code. I am not quite sure how to take use these as replacements for activerecords models though. Need to check out some of the other talks too.

  5. Saw this on HN and just wanted to say I loved it. I appreciate how concrete and prescriptive it is, i.e. I think I could actually go refactor real-world ruby/python code right now to make it fit this model. It also fits well with my own experience of what seems to make codebases painful to work with as they grow and age.

    Have you thought about if it would be feasible and/or useful to calculate a metric (analogous to test coverage percentage or cyclomatic complexity) that measures how much or how little a codebase breaks these guidelines?

  6. Thanks, Danny. I really wanted to make something useful, so I’m really happy to read your response.

    In the second email I sent to the list literally 5 minutes before this happened to go up on YCombinator News I included a rough metric for finding patches to bugs caused by ActiveRecord models having side effects. I’d definitely like to provide more – it’s easy to find immutable classes (they include Adamanium or otherwise use Ruby’s freeze) but Ruby doesn’t have Haskell’s type system, so I don’t know how I’d do a better job of finding classes with side effects. If you can think of more, I’d like to try them and share them.

    I’ll send a link to the email tomorrow when the traffic + signups settle down.

  7. Hi Peter,

    thanks for sharing! I don’t know if you know, but some slides are cutting the transcript. Pages 32 and 33 for example. Just thought to let you know.


  8. Hi Peter,

    I found your model with the two axes of mutability and FX insightful, and it helps me explain why, for instance, you it’s probably better not have queries inside model methods. I connect it with design ideas from other contexts; I usually call “mains” the things you call “shells”, but maybe yours is a better name.

    I have still two doubts. You say that you are proposing two rules, but I cannot understand exactly what those two are… I can’t find them stated explicitly. You seem to give more than two: don’t call mutable things from immutable things, don’t call things with side effects from things that have no side effects are two rules I infer from the talk; and then “Adapters are immutable” seems to be a rule, but if so, then also “Values are immutable is a rule”, “Values have no side effects”….

    In short, it would help me if you stated those two rules explicitly. Could you give them a name? Then we could discuss them more easily. You might take inspiration from Jerry Weinberg’s books; he’s good at giving names to rules.

    Second doubt: where should an ActiveRecord model be in your quadrant?

    Disclaimer: I only read the document, I didn’t watch the presentation.

  9. Matteo: the “two rules” I referred to on the “The Plan” slide (7) are making objects immutable (32) and removing side effects (33). For example, values follow both of the these rules, but Entities only follow the “no side effects” rule. And then, yeah, I go on to talk about “no calling mutable/effectful code from immutable/effectless code” – I can see why that was so confusing and I’m sorry it was unclear. I’ll have to improve the vocabulary and will look into Weinberg’s books.

    I tihnk right now our ActiveRecord models are up with shells, that’s a big part of the “other” I listed near the end. I also think this is a major problem in writing reliable rails apps. I’d like to reduce the size of models by extracting values and adapters (61-63) and, ideally, make them into entities. ActiveRecord leads us to really sprawling, open-ended code, so I know this is a long ways from where our code is now and might not even be possible in a particular app. But I see results from moving incrementally in that direction (20), so I think these concepts are worth understanding and exercising.

  10. Thanks Peter for the clarifications. Now it’s clear. My confusion comes from the fact that I think rules should have the shape “in condition X, do Y”. For this reason I would not call “Make objects immutable” a rule, as it lacks “… when you are in condition X”. Maybe “heuristic” would work better? Or maybe “criterion”, as you use a criterion to discriminate. Immutability is a criterion to distinguish between value objects and entities. How would “The Two Harkins Criteria” sound? “Let’s refactor this code according to responsibilities”. “Let’s refactor this code according to the Harkins Criteria”. Not bad :-)

  11. I am too midwestern to name anything after myself, but any of your other suggestions would be better than “rule”. I’ll play with them and some others, see what makes sense. :)

Leave a Reply

Your email address will not be published.