• Skip to main content
  • Skip to secondary menu
  • Skip to primary sidebar

FromThePage Blog

about crowdsourcing, manuscript transcription, digital humanities and digital documentary editions

  • Home
  • Project Profiles
  • Interviews with Clients
  • Collections
  • Back to FromThePage

Rails: A Short Introduction to before_filter

June 19, 2007 By Ben Brumfield

I just tried out some simple filters in Rails, and am blown away. Up until now, I'd only embraced those features of Rails (like ActiveRecord) that allowed me to omit steps in the application without actually adding any code on my part. Filters are a bit different — you have to identify patterns in your data flow and abstract them out into steps that will be called before (or after) each action. These calls are defined within class definitions, rather than called explicitly by the action methods themselves.

Using Filters to Authenticate
Filters are called filters because they return a Boolean, and if that return value is false, the action is never called. You can use the the logged_in? method of :acts_as_authenticated to prohibit access to non-users — just add before_filter :logged_in? to your controller class and you're set! (Updated 2010: see Errata!)

Using Filters to Load Data
Today I refactored all my controllers to depend on a before_filter to load their objects. Beforehand, each action followed a predictable pattern:

  1. Read an ID from the parameters
  2. Load the object for that ID from the database
  3. If that object was the child of an object I also needed, load the parent object as well

In some cases, loading the relevant objects was the only work a controller action did.

To eliminate this, I added a very simple method to my ApplicationController class:

def load_objects_from_params
if params[:work_id]
@work = Work.find(params[:work_id])
end
if params[:page_id]
@page = Page.find(params[:page_id])
@work = @page.work
end
end

I then added before_filter :load_objects_from_params to the class definition and removed all the places in my subclasses where I was calling find on either params[:work_id] or params[:page_id].

The result was an overall 7% reduction in lines of code -- redundant, error-prone lines of code, at that!
Line counts before the refactoring:

7 app/controllers/application.rb
19 app/controllers/dashboard_controller.rb
10 app/controllers/display_controller.rb
138 app/controllers/page_controller.rb
87 app/controllers/transcribe_controller.rb
47 app/controllers/work_controller.rb
[...]
1006 total

And after:

28 app/controllers/application.rb
19 app/controllers/dashboard_controller.rb
2 app/controllers/display_controller.rb
108 app/controllers/page_controller.rb
69 app/controllers/transcribe_controller.rb
34 app/controllers/work_controller.rb
[...]
937 total

In the case of my (rather bare-bones) DisplayController, the entire contents of the class has been eliminated!

Perhaps best of all is the effect this has on my authentication code. Since I track object-level permissions, I have to read the object the user is acting upon, check whether or not they're the owner, then decide whether to reject the attempt. When the objects may be of different types in the same controller, this can get a bit hairy:

if ['new', 'create'].include? action_name
# test if the work is owned by the current user
work = Work.find(params[:work_id])
return work.owner == current_user
else
# is the page owned by the current user
page = Page.find(params[:page_id])
return page.work.owner == current_user

After refactoring my ApplicationController to call my load_objects_from_params method, this becomes:

return @work.owner == current_user

Filed Under: rails

Reader Interactions

Comments

  1. Anonymous says

    July 17, 2009 at 2:08 pm

    According to the api (see URL below), the filters do not need to return a boolean. It is enough that they redirect or render. Quoting: "If before renders or redirects, the second half of around and will still run but after and the action will not."

    http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html

Primary Sidebar

What’s Trending on The FromThePage Blog

  • How to Learn to Read Shorthand
  • Project Profile: Sewanee Project on Slavery, Race…
  • Interview: Dr. Laura Morreale on Teaching and…
  • Survey on Crowdsourced Transcription Tools
  • UI and Other Fun Stuff
  • Prosopography Hackathon Project: Using Machine…

Recent Client Interviews

An Interview with Erin Wilson of Ohio University Libraries

An Interview with Susannah Ural of the Civil War & Reconstruction Governors of Mississippi Project

An Interview with Olivia Carlisle of the State Archives of North Carolina

An Interview with Paige Roberts of Phillips Academy Archives & Special Collections

An Interview with Riley Bogran of the Sandy Spring Museum

Privacy Policy | Terms & Conditions | About Us | Contact Us

Copyright © 2021 · FromThePage.com