Rails 5 Create module and class level variables

Abhishek Jain

Abhishek Jain

September 5, 2016

This blog is part of our  Rails 5 series.

Rails already provides methods for creating class level and module level variables in the form of cattr** and mattr** suite of methods.

In Rails 5, we can go a step further and create thread specific class or module level variables.

Here is an example which demonstrates an example on how to use it.

1
2module CurrentScope
3  thread_mattr_accessor :user_permissions
4end
5
6class ApplicationController < ActionController::Base
7
8  before_action :set_permissions
9
10  def set_permissions
11    user = User.find(params[:user_id])
12    CurrentScope.user_permissions = user.permissions
13  end
14
15end
16

Now CurrentScope.user_permissions will be available till the lifetime of currently executing thread and all the code after this point can use this variable.

For example, we can access this variable in any of the models without explicitly passing current_user from the controller.

1
2class BookingsController < ApplicationController
3  def create
4    Booking.create(booking_params)
5  end
6end
7
8class Booking < ApplicationRecord
9  validate :check_permissions
10
11  private
12
13  def check_permissions
14    unless CurrentScope.user_permissions.include?(:create_booking)
15      self.errors.add(:base, "Not permitted to allow creation of booking")
16    end
17  end
18end
19

It internally uses Thread.current#[]= method, so all the variables are scoped to the thread currently executing. It will also take care of namespacing these variables per class or module so that CurrentScope.user_permissions and RequestScope.user_permissions will not conflict with each other.

If you have used PerThreadRegistry before for managing global variables, thread_mattr_* & thread_cattr_* methods can be used in place of it starting from Rails 5.

Globals are generally bad and should be avoided but this change provides nicer API if you want to fiddle with them anyway!

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.