Concerns en Ruby on Rails

Los concerns son una forma de abstraer código que se comparte entre diferentes modelos o diferentes controladores.

Se coloca en un módulo y ese módulo se va incluyendo en los archivos que quieres que integren ese código común.

Tanto la carpeta models como la de controllers tienen la carpeta concerns predefinida.

 

Lo primero que tenemos que hacer es generar un modulo que extienda de ActiveSupport.

En este ejemplo vamos a controlar que nivel de permiso tiene un usuario para dejarle o no hacer operaciones en nuestra web.

 

En el directorio concern de models creamos el siguiente modulo:

permissions_concertn.rb

module PermissionsConcern
  extend ActiveSupport::Concern

  def is_normal_user?
    self.permission_level >= 1
  end

  def is_editor?
    self.permission_level >= 2
  end

  def is_admin?
    self.permission_level >= 3
  end

end

 

Ahora en el modelo de clase que vayamos a usarlo, lo incluimos:

user.rb

class User < ApplicationRecord
 .
 . 
 .
  include PermissionsConcern
end

 

A continuación, en la clase User se puede usar los métodos declarados en el módulo incluido.

Ejemplo –> User.last.is_normal_user?

 

En este paso, podremos implementar a nivel de controlador el validar el tipo de usuario que está usando la aplicación.

En el ApplicationController (clase la cual todos los controladores heredan), implementamos el siguiente método protected:

class ApplicationController < ActionController::Base
 . 
 .

  protected

def authenticate_editor!
  redirect_to root_path unless user_signed_in? && current_user.is_editor?
end

def authenticate_admin!
  redirect_to root_path unless user_signed_in? && current_user.is_admin?
end
 .
 .

Esta función verifica si el usuario ha iniciado sesión y si es un tipo de usuario editor o administrador. Si no lo fuera redirecciona a la pagina root del sitio.

 

En este punto, en el controlador de Artículos en nuestro caso, llamamos a los métodos declarados en el ApplicationController para verificar el usuario antes de cada acción y dejarle o no realizar acciones:

class ArticlesController < ApplicationController
 .
 .
 .
  before_action :authenticate_editor!,only:[:new, :create, :update]
  before_action :authenticate_admin!,only:[:destroy]
 .
 .