• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 17/01/2017

Allégez vos contrôleurs avec before_action

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Dans le chapitre précédent, vous avez vu comment récupérer l'utilisateur connecté avec ces trois lignes :

if session[:user_id]
  @current_user = User.find(session[:user_id])
end

Nous l'utilisons actuellement dans la fonction home, mais nous en avons besoin sur toutes les pages. Problème : il n'est pas très élégant de répéter le même code dans toutes les fonctions du contrôleur. Voici comment éviter cela :

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  def home
    set_current_user
  end

  # … def login et def check … 

  private

  def set_current_user
    if session[:user_id]
      @current_user = User.find(session[:user_id])
    end
  end
end

Tout ce que nous avons fait, c’est extraire le code dans une nouvelle fonctionset_current_user que nous appelons dans la page home. Ainsi, nous ne répétons plus qu’une ligne au lieu de trois.

Il y a moyen de faire mieux encore :

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :set_current_user

  def home
  end

  # … def login et def check … 

  private

  def set_current_user
    if session[:user_id]
      @current_user = User.find(session[:user_id])
    end
  end
end

La fonction before_action permet d’appeler la fonction set_current_user avant toutes les autres. Ainsi, quelque soit la vue que vous affichez, si l’utilisateur est connecté, vous aurez accès à la variable @current_user.

Mais il est possible de faire mieux encore ! Là, notre before_action n’agit que sur le contrôleurUsers : il serait parfait qu’il agisse sur tous les contrôleurs. Lisez la première ligne de votre contrôleur :

class UsersController < ApplicationController

Le contrôleur UsersController hérite de la classe ApplicationController, qui ressemble à ceci :

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
end

Tout ce qui sera mis dans cette classe sera récupéré dans les autres contrôleurs. Ce n’est pas une spécificité de Rails, c’est un comportement naturel de Ruby. Il n’y a qu’a déplacer du code pour ne plus jamais avoir à le répéter :

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :set_current_user

  private

  def set_current_user
    if session[:user_id]
      @current_user = User.find(session[:user_id])
    end
  end
end

Nettoyez alors votre contrôleur User :  

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  def home
  end

  # … def login et def check … 
end

Maintenant, dans toutes les vues de votre application, vous aurez à votre disposition la variable @current_user, qui vaudra nil si l’utilisateur n’est pas identifié.

Exemple de certificat de réussite
Exemple de certificat de réussite