How to use Ruby on Rails Concerns

jetthoughts-dev

JetThoughts Dev

Posted on August 18, 2022

How to use Ruby on Rails Concerns

A Rails concern is a module that extends the ActiveSupport::Concern module.

You can use Сoncerns to store common code for several classes there, or for refactoring to separate semantically similar code in separate modules.

A concern provides two blocks:

module SampleConcern
  extend ActiveSupport::Concern

  included do
    ...
  end

  class_methods do
    ...
  end
end
Enter fullscreen mode Exit fullscreen mode

included:

The code inside the included block is evaluated in the context of the including class.

class_methods:

Here you can implement methods that will become methods of the class to which the container is included.

Let’s look at an example:

Concern:

module AuthenticationConcern
  extend ActiveSupport::Concern

  included do
    before_action :authenticate
  end

  private
    def authenticate
      if authenticated_user = User.find_by(id: cookies.encrypted[:user_id])
        current_user = authenticated_user
      else
        redirect_to new_session_url
      end
    end
end
Enter fullscreen mode Exit fullscreen mode

Controller:

class ApiBaseController < ActionController::Base
  include AuthenticationConcern
  ...
end
Enter fullscreen mode Exit fullscreen mode

By using Сoncerns, we have moved the code responsible for user authorization to a separate module.

Testing

Concerns are also convenient in that they can be tested in isolation instead of covering all classes where the concern is included with tests.

require 'rails_helper'
class FakeController < ApplicationController
  include AuthenticationConcern

  def new; end
end
RSpec.describe FakeController, type: :controller do    
  context '#new' do
    context 'valid user'  do
      get :new, headers: {token: 'valid_token'}     
      it { expect(response).to have_http_status(:success) }
    end

    context 'invalid user' do 
      get :new, headers: {token: 'invalid_token'}
      it { expect(response).to redirect_to(new_session_url) }
    end
  end
end
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
jetthoughts-dev
JetThoughts Dev

Posted on August 18, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related