Non-restricting scope and the UserSession class in Rails

Written . Tagged Ruby, 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:

1
2
3
4
5
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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:

1
2
3
4
5
6
7
8
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?.