【问题标题】:Routing Error: uninitialized constant路由错误:未初始化的常量
【发布时间】:2012-05-04 08:02:20
【问题描述】:

我正在尝试为移动 API 设置路由,它应该具有版本化的 api-path。我已经可以让移动 Auth 工作了,它在位于 /controllers/api/v1/mobile/ 的单独控制器 AuthController 中实现。

使用示例:

myapp.com/api/v1/mobile/auth

但是现在我想将我现有的资源控制器注册到这个路径模式作为额外的 api 路由。具体:这将是位于 /controllers/tracker/tasks_controller.rb 的 TasksController。所以我在路由定义中添加了一个移动路由:

# routes.rb
namespace :tracker, path: 'timetracking' do
  resources :tasks, 'jobs'
end

namespace :api do
  namespace :v1 do
    namespace :mobile do
      resources :auth, :only => [:create, :destroy]

      namespace :tracker do    #added mobile route
        resource :tasks, controller: 'tracker/tasks', as: :mobile_tasks
      end
    end
  end
end

但是当我调用 myapp.com/api/v1/mobile/tracker/tasks 时,它会导致错误消息:

Routing Error
uninitialized constant Api::V1::Mobile::Tracker

我特别为这条路线添加了别名 :mobile_tasks,以避免与上面的原始任务路线发生任何冲突。任何想法,如何为这条路线正确设置控制器?

更新#1

将此路由定义为作用域而不是命名空间也不起作用。

scope "/api/v1/mobile/tracker" do
    resources :tasks, controller: 'tracker/tasks', as: :mobile_tasks
end

但这一次,它甚至没有解析路由路径本身。

Routing Error
No route matches [GET] "/api/v1/mobile/tracker/tasks"

我认为这可能是个问题,我的附加 mobile-api 路由试图指向一个完全不同的命名空间 tracker。

【问题讨论】:

  • 遇到了类似的问题,实际上我只需要重新启动rails server。我想它有必要获取名称空间和所有内容中的更改。把它放在那里以防其他人最终从 Google 来到这里!

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


【解决方案1】:

根据http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing,您应该使用范围而不是命名空间。

如果你想将/admin/posts 路由到PostsController(没有Admin:: module prefix),你可以使用:

scope "/admin" do
  resources :posts, :comments
end

【讨论】:

  • 嗨克里斯,感谢您的回答。我用关于你的建议的 rails-output 更新了我的问题文本。
  • 您是否尝试过rake routes 命令以匹配顺序和名称打印出所有已定义的路由?它应该可以帮助您调试此问题。
  • 感谢rake routes 的良好提示。帮我解决了这个问题:)
  • @loybert - 如果您的问题已解决,请跟进!更新您的问题,为正确答案添加评论,甚至添加新答案
  • 嗨@ivar。据我所知,命名空间块太多了,因为它已经隐式设置了父命名空间,所以运行 rake routes 帮助我看到了格式错误的路由路径,看起来有点 /mobile/api /v1/tracker/tracker/tasks。对不起,我的评论不是那么准确,但如果您自己提出问题,我会看一下。 :)
【解决方案2】:

迟到的答案,但仍然可能会有所帮助:

scope '/v1' do  
  resources :articles, module: 'v1'
end

控制器

# app/controller/v1/articles_controller.rb
class V1::ArticlesController < ApplicationController

end

现在你应该可以访问这个网址了:

http://localhost:3000/v1/articles

【讨论】:

    【解决方案3】:

    添加此答案以明确命名空间和范围。

    当你使用命名空间时,它会在指定资源的URL路径前加上前缀,并尝试将控制器定位在与命名空间同名的模块下。

    # config/routes.rb
    namespace :admin do
      resources :posts, only: [:index]
    end
    
    # rake routes
    Prefix Verb URI    Pattern                   Controller#Action
    admin_posts GET    /admin/posts(.:format)    admin/posts#index
    

    当我们添加作用域时,它只会映射给定作用域模式的控制器动作。无需在任何模块下定义控制器。

    # config/routes.rb
    scope :admin do
      resources :posts, only: [:index]
    end
    
    # rake routes
    Prefix Verb URI    Pattern                   Controller#Action
    admin_posts GET    /admin/posts(.:format)    posts#index
    

    请注意,控制器只是没有任何模块命名空间的发布控制器。

    如果我们将path 选项添加到作用域,它将映射到具有指定路径选项的控制器,如下所示

    # config/routes.rb
    scope module: 'admin', path: 'admin' do
      resources :posts, only: [:index]
    end
    
    # rake routes
    Prefix Verb URI    Pattern                   Controller#Action
    admin_posts GET    /admin/posts(.:format)    admin/posts#index
    

    请注意,控制器现在位于管理模块下。

    现在,如果我们想更改路径方法的名称来识别资源,我们可以在作用域中添加as 选项。

    # config/routes.rb
    namespace module: 'admin', path: 'admin', as: 'root' do
      resources :posts, only: [:index]
    end
    
    # rake routes
    Prefix Verb URI    Pattern                  Controller#Action
    root_posts GET    /admin/posts(.:format)    admin/posts#index
    

    你可以看到前缀动词的变化。

    希望对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-24
      • 1970-01-01
      • 2014-02-01
      • 2015-05-23
      • 1970-01-01
      相关资源
      最近更新 更多