Skip to content

Instantly share code, notes, and snippets.

@ngauthier
Created November 19, 2012 15:43
Show Gist options
  • Save ngauthier/4111358 to your computer and use it in GitHub Desktop.
Save ngauthier/4111358 to your computer and use it in GitHub Desktop.
Model Accessors

Model Accessors

I really like this pattern for providing accessors to the models used in a controller. Alternatively, you usually see a before_filter to set the model from the params hash only on the actions that need it. IMO this is abusing a before_filter because the filter chain is for pre-processing the request. This does sort of make sense if you want to redirect away from the page gracefully if the record can't be found, but you can do that by just calling the accessor in a filter to make sure it's there.

This means that views are more like partials with locals, which is nice. It also means the accessor is as easy to test as a named filter. And as usual it pulls the method out of the action to share, which is also nice.

Also, it achieves the same ends as gems that try to OO the view, but without a gem and with terse code. The model can be swapped for a presenter if necessary.

class ProfilesController < ApplicationController
private
def profile
@profile ||= Profile.find(params[:id])
end
helper_method :profile
end
<h1><%= profile.name %></h1>
@Odaeus
Copy link

Odaeus commented Nov 19, 2012

I've been trying this style out recently and really like it. I was using the decent_exposure gem before but don't like the magic of autoloading models by inference.

I've put this in my ApplicationController:

  def self.view_accessor(*names)
    attr_accessor *names
    helper_method *names
  end

@Odaeus
Copy link

Odaeus commented Nov 19, 2012

Oops, can't edit gist comments.

Forgot to note that my style is different in that I'm more likely to assign the value in the body of the action:

class ArticlesController < ApplicationController
  attr_accessor :article

  def new
    self.article = Article.new
  end

  def show
    self.article = Article.find(params[:id])
  end
end

@ngauthier
Copy link
Author

Yup, decent_exposure is good. However I tend to customize / slug routes. Also, I consider every gem added to a project a cost, so I have to strongly justify a gem to add it. This is a simple and obivous pattern, so I don't feel it needs extraction. Metaprogramming w/ a gem is often more complex than the solution itself (in the small).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment