Rails 3:以编程方式获取命名空间中路由列表

19

问题

如何获取我Admin命名空间中所有路由的列表,以便在我的一个测试中使用?

思路

我经常会犯一个错误,就是在创建Admin命名空间中的新控制器时,错误地从ApplicationController继承而不是从AdminController继承。因此,我想编写一个测试来访问我Admin命名空间中的所有路由,并验证每个路由都需要一个已登录的用户。


尝试运行rake routes......它会给你列出在你的应用程序中定义的所有路由。 - LHH
我正在尝试在测试中使用路由列表,所以rake routes对我来说行不通。我需要能够在代码中操纵这个列表。 - Richard Jones
2个回答

23
test_routes = []

Rails.application.routes.routes.each do |route|
  route = route.path.spec.to_s
  test_routes << route if route.starts_with?('/admin')
end

3
如果您愿意,这可以是一行代码: admin_routes = Rails.application.routes.routes.select { |route| route.path.spec.to_s.starts_with? "/admin" }(该代码用于选取所有以“/admin”开头的路由) - Richard Jones
1
我更愿意在控制器上进行过滤,这将导致:Rails.application.routes.routes.select{ |route| route.defaults[:controller] == 'admin' && route.verb =~ 'GET'}(同时也对请求类型进行过滤)。 - Augustin Riedinger
你也可以获取 routes.spec 并在其上调用 .each 循环遍历整个树形结构。如果你按照 literal? 进行过滤,那么将会得到路由的所有字面部分,这通常是我所需要的。 - trcarden

14

如果其他人也想测试命名空间中的所有路由是否需要登录用户,那么我是如何实现的:

ROUTES = Rails.application.routes.routes.map do |route|
  # Turn route path spec into string; use "1" for all params
  path = route.path.spec.to_s.gsub(/\(\.:format\)/, "").gsub(/:[a-zA-Z_]+/, "1")
  verb = %W{ GET POST PUT PATCH DELETE }.grep(route.verb).first.downcase.to_sym
  { path: path, verb: verb }
end

test "admin routes should redirect to admin login page when no admin user is logged in" do
  admin_routes = ROUTES.select { |route| route[:path].starts_with? "/admin" }
  unprotected_routes = []

  admin_routes.each do |route|
    begin
      reset!
      request_via_redirect(route[:verb], route[:path])
      unprotected_routes << "#{route[:verb]} #{route[:path]}" unless path == admin_login_path
    rescue ActiveRecord::RecordNotFound
      unprotected_routes << "#{route[:verb]} #{route[:path]}" unless path == admin_login_path
    rescue AbstractController::ActionNotFound
    end
  end

  assert unprotected_routes.empty?,
    "The following routes are not secure: \n\t#{unprotected_routes.uniq.join("\n\t")}"
  end
end

我欢迎改进。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接