Как получить список контроллеров и действий в ruby ​​на рельсах? - PullRequest
32 голосов
/ 31 декабря 2011

В rails я могу получить имя текущего контроллера через controller_name и текущее действие, вызвав action_name. Я ищу подобное отражение во время выполнения для получения следующего:

  1. Список всех контроллеров в приложении.
  2. Список всех действий в данном контроллере.

Например, я - Контроллер продукта, который выполняет действия «добавить» и «редактировать». Могу ли я получить названия этих действий программно, чтобы показать пользователю, какие операции поддерживаются?

Я посмотрел на метод, который вызывает использование ActionController::Routing::Routes.named_routes.routes.each но я не мог заставить это работать. Я получил неинициализированную константу ActionDispatch::Routing::Routes ошибка, когда я использовал его.

Если есть какой-нибудь хороший учебник или документ, который может помочь мне понять, как отражается способность рельсов. Я искал это, но я в основном получил активные блоги отражения записи. Я ищу что-то, что позволяет мне получать информацию о контроллерах и действиях / методах во время выполнения.
Спасибо,

Tabrez

Ответы [ 4 ]

102 голосов
/ 31 декабря 2011

Самый простой способ получить список классов контроллеров - это:

ApplicationController.descendants

Однако, поскольку классы загружаются лениво, вам нужно будет загрузить все свои классы, прежде чем вы это сделаете.Имейте в виду, что этот метод займет время, и он замедлит вашу загрузку:

Rails.application.eager_load!

Чтобы получить все действия в контроллере, используйте action_methods

PostsController.action_methods

Thisвернет Set, содержащий список всех методов в вашем контроллере, которые являются "действиями" (используя ту же логику, которую использует Rails, чтобы определить, является ли метод допустимым действием для маршрутизации).

5 голосов
/ 25 октября 2017

PostsController.action_methods вернет все действия PostsController, включая унаследованные, это не то, что я хочу, я нашел PostsController.instance_methods(false), который будет возвращать все методы экземпляра PostsController и не включать унаследованные, именно то, что я хочу.

1 голос
/ 29 ноября 2018

У меня была похожая проблема;в моем случае это было для написания тестовых контроллеров.Есть определенные базовые тесты, которые я хочу запускать при каждом действии для определенных контроллеров (например, вернуть 401, если пользователь не вошел в систему).Проблема с решением action_methods заключается в том, что он выбирает все методы класса контроллера, даже если у метода нет соответствующего маршрута в config / rout.rb.

Вот что я в итоге сделал:

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

Итак, если бы вы хотели список действий для PostsController, вы бы сказали:

actions_for_controller('posts')

И вы получите:

['show', 'create', 'edit', 'destroy'] (or whatever)

Если вы хотитесписок всех контроллеров, примерно так должно это сделать:

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
0 голосов
/ 03 апреля 2019

Удаляем неиспользуемые контроллеры и действия.Поэтому я хотел создать исчерпывающий список для отметки для удаления.Вот что я в итоге сделал

ApplicationController.descendants.each do |controller|
  puts controller.name
  controller.action_methods.each do |action|
    puts '  ' + action
  end
end

Это обеспечивает хороший список действий с отступом под именами контроллеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...