Dans Rails, je peux obtenir le nom du contrôleur actuel via le nom du contrôleur et l'action en cours en appelant nom_action. Je recherche une réflexion similaire à l'exécution pour obtenir les éléments suivants:
Par exemple, j’ai un contrôleur de produit ayant les actions "ajouter" et "éditer". Puis-je extraire les noms de ces actions par programme pour montrer à l'utilisateur quelles opérations sont supportées?
J'ai examiné une méthode qui appelle l'utilisation de ActionController::Routing::Routes.named_routes.routes.each
mais je ne pouvais pas le faire fonctionner. J'ai eu l'erreur constante ActionDispatch::Routing::Routes
non initialisée quand je l'ai utilisée.
S'il existe un bon didacticiel ou un document pouvant m'aider à comprendre les capacités de réflexion de Rails. Je l'ai cherché mais j'ai surtout eu des blogs actifs sur la réflexion. Je recherche quelque chose qui me permette d'obtenir des informations sur les contrôleurs et les actions/méthodes au moment de l'exécution.
Merci,
Tabrez
Le moyen le plus simple d’obtenir une liste des classes de contrôleur est:
ApplicationController.descendants
Cependant, comme les classes sont chargées paresseusement, vous devrez charger toutes vos classes avant de le faire. Gardez à l'esprit que cette méthode prendra du temps et ralentira votre démarrage:
Rails.application.eager_load!
Pour obtenir toutes les actions dans un contrôleur, utilisez action_methods
PostsController.action_methods
Ceci renverra une Set
contenant une liste de toutes les méthodes de votre contrôleur qui sont des "actions" (en utilisant la même logique que Rails utilise pour décider si une méthode est une action valide vers laquelle se diriger).
PostsController.action_methods
renverra toutes les actions de PostsController
, y compris celles héritées, ce n'est pas ce que je veux, j'ai trouvé PostsController.instance_methods(false)
, ce qui renverra toutes les méthodes d'instance de PostsController
sans inclure héritées, exactement ce que je veux.
J'avais un problème similaire; dans mon cas, c'était pour écrire des tests de contrôleur. Je souhaite exécuter certains tests de base sur chaque action de certains contrôleurs (par exemple, renvoyer 401 si l'utilisateur n'est pas connecté). Le problème avec la solution action_methods est qu’il récupère toutes les méthodes de la classe du contrôleur, même si la méthode n’a pas de route correspondante dans config/routes.rb.
Voici ce que j'ai fini par faire:
def actions_for_controller(controller_path)
route_defaults = Rails.application.routes.routes.map(&:defaults)
route_defaults = route_defaults.select { |x| x[:controller] == controller_path }
route_defaults.map { |x| x[:action] }.uniq
end
Donc, si vous vouliez une liste d’actions pour PostsController, vous diriez:
actions_for_controller('posts')
Et vous auriez:
['show', 'create', 'edit', 'destroy'] (or whatever)
Si vous voulez une liste de tous les contrôleurs, quelque chose comme ceci devrait le faire:
def controllers_list
route_defaults = Rails.application.routes.routes.map(&:defaults)
files = route_defaults.map { |x| "#{x[:controller]}_controller" }.uniq
files -= ['_controller']
files.map { |x| x.split('/').map(&:camelize).join('::').constantize }
end