Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

LABS
Messages Not Types: Exploring Ruby's Conversion Protocols

Duck typing is a style of programming that relies on what an object does, rather than on what it is. Avoiding class dependencies results in highly flexible code. Ruby’s conversion protocols, used throughout the core and standard libraries, are a great example of the power of duck typing.

Read more »

LABS
Stop leaky APIs

There are many blogs about how to expose an API for a Rails application and many times I look at this and am concerned about how these examples often leak the application design and the schema out through the API. When this leak occurs a change to the application internals can ripple out and break clients of an API, or force applications to namespace URI paths which I feel is unnecessary and ugly.

Read more »

LABS
Stop leaking ActiveRecord throughout your application

Extending ActiveRecord::Base leaks a powerful API throughout an application which can lead to tempting code which breaks good design. Take the classic blog example where you may want to retrieve the latest posts by a given author. You may have seen, or even written code that gets the dataset you need straight into the controller or view:

Post.where(author_id: author_id).limit(20).order("created_at DESC").each { ...

Read more »

LABS
Refactoring the Deeply-Nested Hash Antipattern

On a few different Ruby projects, I have seen an antipattern emerge involving nested hashes.

For example, consider this simple question-and-answer command-line script:

QUIZ = { question_1: { prompt: "What is your name?" }, question_2: { prompt: "What is your favorite color?" } } answers = {} QUIZ.each do |name, question_hash| print question_hash[:prompt], " " answers[name] = gets.chomp end p answers

The QUIZ constant isn’t too hard to understand.

Read more »

LABS
The Radically Refactored Rails Roundup

I want to talk about something that's been bugging me for a long time in Rails. I want to talk about it, but a lot of smart people have already said what I have to say recently. They've said it rather well.

Here's the upshot: Rails makes it look like you're supposed to have model objects (subclasses of ActiveRecord::Base), controller classes (subclasses of ActionController::Base), and view templates, and that's it. Maybe some observers (subclasses of ActiveRecord::Observer). For the most part, Rails style is to push as much behavior into the model as possible. "Skinny controllers, skinny views, fat models," they said.

Well, object obesity is a growing problem in the Rails world, because we've been shoving so much responsibility on our poor model objects that they can barely hold themselves up. They're particularly hard to test, because while you're mainly interested in testing your domain logic, to make one of these objects in a test you often need to persist it in the database first. That's just crazy. And slow.

Rails is no more exempt from the utility of the Single Responsibility Principle than any other environment. What if we separated the concerns of domain logic and persistence?

For a while I thought I might be the crazy one, but it turns out I'm not alone in thinking this. We're seeing a renaissance of classical OO patterns in the Rails world as people realize that throwing everything in a handful of objects doesn't scale with application complexity.

The Roundup

  • The earliest post I've seen is from James Golick in early 2010, who calls it Crazy, Heretical, and Awesome. As James writes,

    Ever wondered why it seems impossible to write a really good state machine plugin — or why file uploads always seem to hurt eventually, even with something like paperclip? It's because these things don't belong coupled to persistence. [...] A file upload handler shouldn't have to worry about how the name of the file gets stored to the database, let alone where it is in the persistence lifecycle and what that means. Are we in a transaction? Is it before or after save? Can we safely raise an error?

    I also love the objection he hears the reader raise:

    "But then I'll have all these extra classes in my app!"

    I've heard this objection too. I don't get it. Some people seem to have the idea that the fewer classes you have, the easier it is to maintain the app. Maybe it comes from being used to 3000-line classes. Having more of those would be a pain. But by breaking up responsibility into cohesive units, each class becomes comprehensible, which is of the utmost importance in software development, especially as the complexity of the app and the size of the team grow.

  • This past July, the storm began to gather, as Avdi Grimm got all Fowler on Rails' ass. He also gives a shout out to Jeff Casimir's Draper, which I haven't gotten to use yet but I am itching to try. People who have used it are saying good things.

  • Then Piotr Solnica wrote about "Making ActiveRecord Models Thin". Don't miss the rich discussion in the comments. Also, make sure you read the section "Well Defined API". The part where he writes,

    Your Domain Model should have an interface to every action your application should be able to perform. If you have an online shop where a user can buy a product then with a well-written Rails application you should be able to fire up the console and be able to easily perform this operation. If it’s not so simple then you probably want to think about your model implementation again.

    Mmm, yeah. That's good medicine.

  • Coming out of that discussion in the comments, Giles Bowkett re-raised a point from James' piece, that not all apps will need this kind of treatment, because not all apps will be complex enough to feel the pain. Giles writes,

    I don't think there's really any debate here at all, except for one crucial question: where do you mark the threshold? How do you decide when your code needs this split?

    Great question.

  • Next up, the great Steve Klabnik calls Plain Old Ruby Objects "The Secret to Rails OO Design", focusing on the ways they can improve the structuring of view logic. He explains the problem with Rails this way:

    [T]here’s something special about Rails which seems to lure you into the trap of never breaking classes down. Maybe it’s that lib/ feels like such a junk drawer. Maybe it’s that the fifteen minute examples only ever include ActiveRecord models.

    He followed that post up with another awesome one about writing presenters. Do give them a read.

Any good articles I've missed? Leave a comment and let me know.