The following blog post contains material either currently found or soon to be incorporated into my new book, "Easy Active Record for Rails Developers". Among many other topics, you'll learn about model generation, migrations, validations, associations, scopes, joins, includes, forms integration, nested forms, and model testing with RSpec and FactoryGirl. The book is now available, head over to this website's home page to learn more.


One of the great advantages of working with various clients is the opportunity to learn from different implementational approaches. Currently I’m helping a client out with a particularly well-architected Rails application, one which uses several gems that I’d been unfamiliar with prior to this project. One gem in particular has really captured my attention, as it can dramatically reduce the amount of boilerplate code you’d otherwise have to write when building RESTful controllers. That gem is decent_exposure and it was created by the Rails experts at Hashrocket.

RESTful controllers are great because they follow a conventional format that is immediately recognizable by any Rails developer familiar with the concept, meaning less time is spent deciphering fellow developers’ intent and naming conventions. For instance, a RESTful show action is pretty much guaranteed to look like this:

class GamesController < ApplicationController

  ...

  def show
    @game = Game.find(params[:id])
    respond_with(@game)
  end

  ...

end

The show action is then typically accessed via a URL like this http://arcadenomad.com/games/12. The routing convention dictates that the parameter (in this case, 12) is passed into the show method, which can then be used to query the database for a record associated with that primary key. The decent_exposure developers argue that because everybody knows the find method is going to be used for this purpose, shouldn’t we just take that for granted to and automate the call altogether? This means that in the simplest case the show method doesn’t even have to appear in your RESTful controller. Read that last sentence a few times to let it sink in. The reduction in code isn’t limited to show; in fact given a standard RESTful controller enhanced with decent_exposure, the only actions you’ll even have to bother including are create and update, and even those are pretty devoid of code compared to what you’re probably used to seeing.

The decent_exposure developers seek to resolve another issue: eliminating the exposure of instance variables within your views on the basis that doing so breaks encapsulation. This means when using decent_exposure-enhanced controllers you would no longer reference @game within your show action’s corresponding view, but instead just reference game, which is a method exposed by decent_exposure to the view that provides the view with access to the corresponding model’s various attributes, methods, and other features.

Installing decent_exposure

Install decent_exposure by adding the following line to your project Gemfile:

gem 'decent_exposure'

Save the changes and run bundle to install the gem.

Adding decent_exposure to Your Controllers

With the gem installed, you can quickly get started updating your controllers to use decent_exposure. I’ll revise the aforementioned Games controller to use decent_exposure, thereby giving you a well-rounded understanding of what’s possible. Begin by exposing the Game model at the top of the controller:

class GamesController < ApplicationController

  respond_to(:html)
  expose(:game)

end

With Game exposed, decent_exposure now knows to begin working its magic in response to various action requests. Here’s what the complete revised Games controller looks like:

class GamesController < ApplicationController

  respond_to(:html)
  expose(:game)

  def create
    game.save
    respond_with(game)
  end

  def update
    game.save
    respond_with(game)
  end

end

I know it’s difficult to believe I didn’t forget to include some code, but that it really the complete decent_exposure-enhanced controller! All that remains is to revise your views to use the exposed methods rather than instance variables (again, just remove the @ from the instance variables), and you’re done.

Further Reading

There’s no doubt that some of what decent_exposure does seems like pure magic but I can assure you it is very well done and in my opinion a required gem when your application uses conventional RESTful controllers. In order to gain a more well-rounded understanding of all that decent_exposure has to offer, check out the following resources:

  • decent_exposure README: This is the place to begin in order to understand the gem’s basic features.
  • http://decentexposure.info: This is the decent_exposure gem’s companion website, and it contains several lengthy pages explaining the gem’s various fundamental and advanced features.

Comments