我们的Rails 3.2应用程序有管理面板。管理面板分为模块。例如,有Admin::Searching
。我想重构一些重复和硬编码的部分。例如:
<ul class='searching_nav'>
<% %w(tests fuzzy stats terms hits).each do |tab| %>
<li class="<%= css_nav(tab) %>"><%= link_to tab.humanize, [:admin, :searching, tab] %></li>
<% end %>
</ul>
正在搜索导航部分,添加另一个控制器后,您必须手动更改它。
我想要的是,获取Admin::Searching
中所有控制器的列表(此命名空间中的控制器是Admin::AdminController
的子类)。我相信有可能从Rails api以优雅的方式做到这一点。然后它可以推广到所有模块选项卡。
我已经尝试检查Admin :: AdminController.subclasses,但是该数组中的类是延迟加载的,所以在点击Terms
之后,例如,在服务器重启后,只有一个元素[Admin::Searching::TermsController]
,之后访问其他模块还有其他控制器。我可以迭代它们并基于controller_path
结果,仅过滤admin/search
个控制器。也许有可能从路线结束?我的意思是,我可以从Rails.application.routes.routes中获取给定名称空间中的所有控制器吗?
我不想进入文件系统。我知道我可以使用Dir
扫描管理员/搜索目录,但效率很低。
答案 0 :(得分:2)
我有一个很好的答案描述Module#constants
和Module#const_get
的使用,但后来我读到你问题的后半部分,并意识到这种技术可能不会出于同样的原因Admin::AdminController.subclasses
没有 - 这是因为Rails根据需要懒洋洋地加载控制器类。
在您的情况下,我可能最终会进行目录扫描。你认为它效率低下,但是当进行动态加载和填充时,Rails和许多Ruby宝石最终会进入文件系统。
现在,您希望在加载之前找到所有(相关)控制器。结合生产中的洞察力,控制器的数量不会改变。
我想说的是,继续进行Dir
扫描,但是在初始值设定项(config/initializers
下的文件)中进行扫描,因此它只会在开始时执行一次你的应用程序。
所以,可以想象,
# config/initializers/admin.rb
module Admin
CONTROLLERS = begin
# Do a directory scan of app/controllers/admin looking for relevant files
end
end