• 20 hours
  • Medium

Free online content available in this course.

course.header.alt.is_certifying

Got it!

Last updated on 1/17/17

Allégez vos contrôleurs avec before_action

Log in or subscribe for free to enjoy all this course has to offer!

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é.

Example of certificate of achievement
Example of certificate of achievement