Close and Go BackBack to Viget

Wrapping Rails Session Hash: Follow Up

Matt Swasey
Matt Swasey, Former Staffer, October 08, 2009

The other week I wrote about wrapping your Rails session variables in current_object methods. There is, however, a performance related bug in line 5 of the code I posted:

class ApplicationController < ActionController::Base  
  helper_method :current_account  
    
  def current_account  
    @current_account ||= Account.find_by_id(session[:current_account_id])  
  end  
  
  def current_account=(account)  
    session[:current_account_id] = account.try(:id)  
  end  
end 

If session[:current_account_id] is nil, current_account will make a useless database query each time it is called. This would happen if you are calling current_account on a public page while a user has yet to log in.

We can fix this in the following way:

...
def current_account
  if session[:current_account_id]
    @current_account ||= Account.find_by_id(session[:current_account_id])
  end
end
...

The above code will only evaluate @current_account if session[:current_account_id] has been set, otherwise it will return nil without hitting the database. Once session[:current_account_id] is set, it will hit the database a single time, memoize the result in @current_account, and return @current_account for the duration of the Rails request cycle. This should help take some load off the database.

If anyone has an even simpler solution, please let me know in the comments!

blog comments powered by Disqus

Next entry: Developer Day Boulder Wrapup

Previous entry: Database Taxonomy

We're the Developers

at Viget Labs. We write about web development trends, tips, best practices, industry events, and our projects — all with an emphasis on Ruby on Rails.

Contact Us

Have any questions, comments, ideas, or secrets to share? Let us know.


How many minutes in an hour?

Sorry, you need to have Javascript enabled to use this form. (Don't blame us, blame the spammers!) If you'd like to contact us, please visit our Contact page.