Non-restricting scope and the UserSession class in Rails

Written February 19, 2009 at 23:13 CET. Tagged Ruby and Ruby on Rails.

Just a quick Ruby on Rails tip. This is how I implemented a method to either return a scoped subset of a table or all records:

class UserSession
  def viewable_posts
    admin? ? Post.scoped({}) : Post.published
  end
end

By using Post.scoped({}) rather than Post.all, you get a named scope proxy back, meaning that you can chain other scopes onto it and that the query is not executed until necessary.

The UserSession class, by the way, is a nice idea I picked up somewhere. It's a model without an underlying table that you initialize with the Rails session and that encapsulates simple authentication/session logic.

The model:

class UserSession
  
  def initialize(session)
    @session = session
  end
  
  def login(params)
    @session[:is_admin] = !Site.password.blank? && Site.password==params[:password]
  end
  
  def logout
    @session[:is_admin] = nil
  end
  
  def admin?
    !!@session[:is_admin]
  end
  
  def viewable_posts
    admin? ? Post.scoped({}) : Post.published
  end
  
end

Site is a configuration object.

The controller defines methods to access an instance of this object from controller instances and views:

class ApplicationController < ActionController::Base
 
  def user_session
    @user_session ||= UserSession.new(session)
  end
  helper_method :user_session

end

Used like e.g. user_session.admin?.