Rails 3使用命名空间进行路由

时间:2011-07-22 10:16:21

标签: ruby-on-rails ruby-on-rails-3 routing namespaces routes

尝试访问以下网址时,出现 404错误页

  

dev.mydomain.com/api

而我的routes.rb文件提到这条路线确实存在:

的routes.rb

constraints :subdomain => 'dev' do
  root :to => 'developers/main#index', :as => :developers
  namespace 'api', :as => :developers_api do
    root :to => 'developers/apidoc/main#index'
  end
end

佣金路线

         developers   /(.:format)      {:subdomain=>"dev", :controller=>"developers/main", :action=>"index"}
developers_api_root   /api(.:format)   {:subdomain=>"dev", :controller=>"api/developers/apidoc/main", :action=>"index"}

控制器

/app/controllers/developers/apidoc/main_controller.rb

class Developers::Apidoc::MainController < Developers::BaseController
  def index
  end
end

日志

[router]: GET dev.mydomain.com/api dyno=web.1 queue=0 wait=0ms service=14ms status=404 bytes=0
[web.1]: Started GET "/api"
[web.1]: ActionController::RoutingError (uninitialized constant Api::Developers)

3 个答案:

答案 0 :(得分:5)

我猜测问题是您的路线指向api/developers/apidoc/main,但您的班级仅为Developers::Apidoc::MainController。您不应该使用api命名该路由,也不应将Api添加到控制器的命名空间 - Api::Developers::Apidoc::MainController

答案 1 :(得分:3)

要记住的另一个重要因素是路由命名空间需要伴随的目录路径才能保持一致。出错也会导致这样的错误:

Routing Error

uninitialized constant Api::Developers

就我而言,我有一个这样的路线结构:

namespace "api" do
  namespace "developers" do
    ...
  end
end

文件夹/目录结构应该是 app / controllers / api / developers /

答案 2 :(得分:1)

TL; DR namespace替换为scope

给出以下文件夹结构

 Rails.root
  |
  +-- app/
  |    |
  |    +-- controllers/
  |         |
  |         +-- jobs_controller.rb
  +-- config/
       |
       +-- routes.rb

routes.rb下方的代码段会出现错误ActionController::RoutingError: uninitialized constant Api:

namespace :api do
  namespace :v1 do
    resources :jobs
  end
end

以下作品:

scope :api do
  scope :v1 do
    resources :jobs 
  end
end

Rails Routing from the Outside In简要提到了原因:

  

名称空间范围将自动添加:as以及。{   :module:path前缀。

事实上,命名空间只是一个包含预定义选项的范围包装器:

# File actionpack/lib/action_dispatch/routing/mapper.rb, line 871
def namespace(path, options = {})
  path = path.to_s

  defaults = {
    module:         path,
    path:           options.fetch(:path, path),
    as:             options.fetch(:as, path),
    shallow_path:   options.fetch(:path, path),
    shallow_prefix: options.fetch(:as, path)
  }

  scope(defaults.merge!(options)) { yield }
end