嵌套命名空间路由转到错误的控制器



使用 Rails 3.0.7,我正在为我们的应用程序创建一个 API,我有这个设置:

路线.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.rbapp/controllers/users_controller.rb文件以及我的app/controllers/api/v1/application_controller.rbapp/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 - 随意评论我忽略的任何约定,我不应该成为或其他我可能搞砸的事情:)

skip_before_filter通常也为之前的过滤器获取符号参数,而不是您希望跳过的。只要应用了正确的范围/命名空间,控制器名称就不必是唯一的。

  • API/users_controller
  • 管理员/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

Rails有点令人困惑,但我也有类似的问题。您可以采取以下步骤来确保不会遗漏任何小代码问题。(这最终导致我在命名空间控制器中发现了语法错误(。

  1. 运行 bundle exec rake routes 以生成哪些路由链接到哪个控制器和操作的列表。如果这很好,请转到步骤 2。如果没有,请修复您的路由文件,然后重试。(关于这个有很多很好的教程,所以我就不赘述了(
  2. 进入 rails 控制台,然后加载控制器类。如果它不起作用,您可能发现了语法中的错误。这是我尝试加载Api::V2::CampaignsController时控制台上发生的事情。

    irb> API::V2::CampaignController

    => 广告系列控制器

注意:Rails 将所有请求定向到错误的控制器(基于 Rails 加载控制器类的奇特逻辑(。它应该转到 Api::V2::CampaignController,但它正在加载 CampaignController。

您还可以在控制台中通过以下方式进行验证:

> app.get '/api/v2/campaigns.json'
> app.controller.class
=> CampaignsController
# This is not the expected controller. 

这最终成为我从 Api::V2::CampaignController 扩展的类中的语法问题。

这有点令人难以置信,但希望这对其他人有所帮助。

最新更新