Comment partager du code entre différents contrôleurs dans un projet Ruby on Rails

Il est courant de devoir échanger du code entre différents contrôleurs. C'est notamment le cas lors d'une déconnexion et d'une suppression de compte, pour supprimer la session utilisateur.

Même si les contrôleurs doivent contenir un minimum de code, il est courant de devoir réutiliser du code dans plusieurs contrôleurs. Un exemple tout simple est le cas d'une déconnexion et d'une suppression de compte, dans les deux cas on souhaite supprimer la session de l'utilisateur courant etc.

Il faut donc trouver une solution propre pour ne pas se répéter (DRY), et pouvoir utiliser un code commun à ces deux emplacements. Suivant les cas il existe différentes manières de partager du code entre différents contrôleurs :

Si le code est un ensemble de fonctions qui n'a pas besoin d'accéder à l'état du contrôleur, placer ce dernier dans un module qui sera appelé séparemment.
 

 module GMapsAPI
 def get_geolocation(emplacement)
   ...
 end
end
 class ContactController < ApplicationController
 def index
   position = GMapsAPI::get_geolocation('Lausanne')
 end
end


Si le code a besoin d'accéder à l'état du contrôleur, et qu'il peut être utilisé dans tous les contrôleurs, placer ce dernier dans ApplicationController.
 

 class ApplicationController < ActionController::Base
 before_filter :set_application_name
 
 def set_application_name
   @application_name = 'Mon application'
 end
end
 class ContactController < ApplicationController
 def index
   # @application_name est accessible ici
 end
end


Si le code a besoin d'accéder à l'état du contrôleur et qu'il peut être utilisé par plusieurs contrôleurs partageant des fonctionnalités similaires (plusieurs contrôleurs demandant une authentification par exemple), utiliser une classe de base.
 

 class PrivateController < ApplicationController
 require_role :admin
end
 class ContactController < PrivateController
 def index
   # cette action n'est accessible qu'aux admins
 end
end
 def AddressController < ApplicationController
 def index
   # cette action est accessible à tout le monde
 end
end


Si le code a besoin d'accéder à l'état du contrôleur et qu'il peut être utilisé par une partie des contrôleurs qui ne sont pas forcémment liés, placer le code dans un module et inclure ce module dans tous les contrôleurs nécessaires.
 

 module GMapsAPI
 def get_geolocation(emplacement)
   ...
 end
end
 class ContactController < ApplicationController
 include GMapsAPI
 
 def index
   position = get_geolocation('Lausanne')
 end
end


Ce contenu a été réalisé par accolade.ch (Raphaël Emourgeon) sous licence Creative Commons.