嵌套命名空间路由到错误的控制器
Posted
技术标签:
【中文标题】嵌套命名空间路由到错误的控制器【英文标题】:nested namespace route going to wrong controller 【发布时间】:2012-05-14 11:38:15 【问题描述】:使用 Rails 3.0.7,我正在为我们的应用程序创建一个 API,并且我有这样的设置:
routes.rb
namespace :api do
namespace :v1 do
match "connect" => "users#login", :via => :post
match "disconnect" => "users#logout", :via => :post
resources :users
match "users/:id/foos" => "foos#list", :via => :get
match "users/:id" => "users#update", :via => :put
match "foos/:id/bars" => "bars#list_by_foo", :via => :get
match "foos/:id" => "foos#show", :via => :get, :constraints => :id => /\d+/
match "bars/:id" => "bars#show", :via => :get
end
end
# other routes here e.g.
match "users/find" => "users#find_by_name", :via => :get
match "users" => "users#create", :via => :post
然后我有我的常规app/controllers/application_controller.rb
和app/controllers/users_controller.rb
文件以及我的app/controllers/api/v1/application_controller.rb
和app/controllers/api/v1/users_controller.rb
文件,定义如下:
class Api::V1::ApplicationController < ApplicationController
before_filter :verify_access
def verify_access
# some code here
end
end
class Api::V1::UsersController < Api::V1::ApplicationController
skip_before_filter, :except => [:show, :update, :delete]
end
在一切似乎都正常工作之前,直到我覆盖了由 UsersController 和 Api::V1::UsersController 共享的方法——现在似乎一切都指向 UsersController,即使我正在通过api/v1/users 路由。
我已经无计可施了。有什么建议?谢谢。 PS - 随意评论我不应该忽略的任何约定或其他我可能搞砸的事情:)
【问题讨论】:
原来我只需要使我所有的控制器名称都是唯一的,而不管命名空间如何。 Here's a link that helped 【参考方案1】:Rails 有点令人困惑,但我遇到了类似的问题。以下是您可以采取的一些步骤,以确保您不会遗漏任何小代码问题。 (这最终导致我在命名空间控制器中发现了一个语法错误)。
-
运行
bundle exec rake routes
以生成哪些路由链接到哪些控制器和操作的列表。如果这很好,则转到第 2 步。如果没有,请修复您的路线文件并重试。 (这方面有很多很好的教程,所以我不会详细介绍)
进入 rails 控制台,加载控制器类。如果它不起作用,您可能已经发现了语法错误。这是我尝试加载 Api::V2::CampaignsController
时控制台上发生的情况。
irb> Api::V2::CampaignsController
=> 活动控制器
注意:Rails 将所有请求定向到错误的控制器(基于 Rails 加载控制器类的奇特逻辑)。它应该转到 Api::V2::CampaignsController,但它正在加载 CampaignsController。
您也可以在控制台中验证它:
> app.get '/api/v2/campaigns.json'
> app.controller.class
=> CampaignsController
# This is not the expected controller.
这最终成为我从 Api::V2::CampaignsController 扩展的类中的语法问题。
这有点令人难以置信,但希望这对其他人有所帮助。
【讨论】:
【参考方案2】:skip_before_filter
通常也为之前的过滤器采用符号参数,而不是您希望跳过的。只要应用了正确的范围/命名空间,控制器名称就不必是唯一的。
例子
api/users_controller admin/users_controller users_controller然后是每个控制器的代码
class Api::V1::UsersController < Api::V1::BaseController
end
class Admin:UsersController < Admin::BaseController
end
class UsersController < ApplicationController
end
然后是路线
MyApp::Application.routes.draw do
scope :module => "api" do
namespace :v1 do
resources :users
end
end
namespace :admin do
resources :users
end
resources :users
end
【讨论】:
以上是关于嵌套命名空间路由到错误的控制器的主要内容,如果未能解决你的问题,请参考以下文章