J'utilise la gemme Devise authentication dans mon projet Rails et je souhaite modifier les clés utilisées dans les alertes flash. (Devise utilise: avis et: touches flash d’alerte, mais je souhaite les changer en: succès et: erreur pour pouvoir afficher de jolies cases vert/rouge avec Bootstrap .)
Je souhaite donc pouvoir en quelque sorte remplacer la méthode set_flash_message
dans DeviseController .
Voici la nouvelle méthode:
def set_flash_message(key, kind, options = {})
if key == 'alert'
key = 'error'
elsif key == 'notice'
key = 'success'
end
message = find_message(kind, options)
flash[key] = message if message.present?
end
Mais je ne sais pas où le mettre.
UPDATE:
Sur la base d'une réponse, j'ai créé un fichier config/initializers/overrides.rb avec le code suivant:
class DeviseController
def set_flash_message(key, kind, options = {})
if key == 'alert'
key = 'error'
elsif key == 'notice'
key = 'success'
end
message = find_message(kind, options)
flash[key] = message if message.present?
end
end
Mais cela provoque une erreur sur chaque action Devise:
Erreur de routage: méthode non définie 'prepend_before_filter' pour Devise :: SessionsController: Class
Si vous essayez de rouvrir une classe, la syntaxe est la même que pour déclarer une nouvelle classe:
class DeviseController
end
Si ce code est exécuté avant la déclaration de classe réelle, il hérite de Object au lieu d'étendre la classe déclarée par Devise. Au lieu de cela, j'essaie d'utiliser ce qui suit
DeviseController.class_eval do
# Your new methods here
end
De cette façon, vous obtiendrez une erreur si DeviseController
n'a pas été déclaré. En conséquence, vous finirez probablement avec
require 'devise/app/controllers/devise_controller'
DeviseController.class_eval do
# Your new methods here
end
Utiliser Rails 4 @aceofspades answer n'a pas fonctionné pour moi.
Je continuais à avoir besoin ': cannot load such file -- devise/app/controllers/devise_controller (LoadError)
Au lieu de viser avec l'ordre de chargement des initialiseurs, j'ai utilisé le hook d'événement to_prepare
sans instruction require. Cela garantit que la correction du singe se produit avant la première demande. Cet effet est similaire à after_initialize
hook, mais garantit que la correction de singe est réappliquée en mode développement après un rechargement (en mode prod, le résultat est identique).
Rails.application.config.to_prepare do
DeviseController.class_eval do
# Your new methods here
end
end
N.B. la documentation de Rails sur to_prepare
est toujours incorrecte: consultez cette question de Github
Qu'en est-il de l'ajout de l'initialiseur de substitution et de l'alias pour les attributs du hachage flash, comme ceci:
class ActionDispatch::Flash::FlashHash
alias_attribute :success, :notice
alias_attribute :error, :alert
end
Cela devrait permettre à votre application de lire flash [: notice] ou flash [: succès] (flash.notice et flash.success).
Dans votre fichier d'initialisation:
module DeviseControllerFlashMessage
# This method is called when this mixin is included
def self.included klass
# klass here is our DeviseController
klass.class_eval do
remove_method :set_flash_message
end
end
protected
def set_flash_message(key, kind, options = {})
if key == 'alert'
key = 'error'
elsif key == 'notice'
key = 'success'
end
message = find_message(kind, options)
flash[key] = message if message.present?
end
end
DeviseController.send(:include, DeviseControllerFlashMessage)
C'est assez brutal mais fera ce que vous voulez. Le mixin supprimera la méthode précédente set_flash_message, forçant les sous-classes à revenir à la méthode mixin.
Edit: Self.included est appelé lorsque le mixin est inclus dans une classe. Le paramètre klass est la classe dans laquelle le mixin a été inclus. Dans ce cas, klass est DeviseController et nous appelons remove_method dessus.
Vous devez écraser DeviseController tout en conservant sa super-classe dans votre initialiseur.
Quelque chose comme:
class DeviseController < Devise.parent_controller.constantize
def set_flash_message(key, kind, options = {})
if key == 'alert'
key = 'error'
elsif key == 'notice'
key = 'success'
end
message = find_message(kind, options)
flash[key] = message if message.present?
end
end
Je sais que c'est un vieux fil, mais cela pourrait quand même être utile. Vous devriez pouvoir demander le fichier depuis le répertoire gem en utilisant le moteur appelé chemin_du_fichier.
nécessite File.expand_path ('../../ app/helpers/devise_helper', Devise :: Engine.called_from) nécessite File.expand_path ('../../ app/controllers/devise_controller ', Devise :: Engine.called_from).
C’est le genre de chose que vous voudrez mettre sur le dossier d’initialisation Rails, car c’est une configuration personnalisée pour cette application en particulier, vous devriez ensuite l’utiliser comme suit:
class DeviseController
def set_flash_message(key, kind, options = {})
if key == 'alert'
key = 'error'
elsif key == 'notice'
key = 'success'
end
message = find_message(kind, options)
flash[key] = message if message.present?
end
end
alors, vous devriez avoir le comportement attendu. J'espère que ça m'aidera car je n'ai pas testé, ni donné de feedback, et je vous aiderai à essayer quelque chose de différent.