0

我们的 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 获取给定命名空间中的所有控制器吗?

我不想进入文件系统。我知道我可以使用它来扫描 admin/searching 目录,Dir但它效率低下。

4

1 回答 1

2

我有一个很好的答案来描述它的使用,Module#constantsModule#const_get后来我通读了你问题的后半部分,并意识到这种技术可能不会因为同样的原因不起作用Admin::AdminController.subclasses——那是因为 Rails 延迟加载控制器类根据需要。

在您的情况下,我可能最终会进行目录扫描。你认为它效率低下,但是 Rails 和许多 Ruby gem 在进行动态加载和其他东西时最终都会进入文件系统。

现在,您想在加载之前找到所有(相关的)控制器。再加上在生产中控制器的数量不会改变的洞察力。

我想说的是,继续进行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
于 2013-02-07T14:10:27.160 回答