Rails路由和控制器模块-namespacing?

时间:2013-03-20 18:28:04

标签: ruby-on-rails

我无法为控制器创建模块,并让路由指向控制器内的该模块。

出现此错误:

Routing Error
uninitialized constant Api::Fb

所以,这就是我的路线设置方式:

namespace :api do
  namespace :fb do
    post :login
    resources :my_lists do
      resources :my_wishes
    end
  end
end

在我的fb_controller中,我希望包含能够提供如下路径的模块:

/api/fb/my_lists

这是我的一些fb_controller:

class Api::FbController < ApplicationController
  skip_before_filter :authenticate_user!, :only => [:login]

  include MyLists # <-- This is where i want to include the /my_lists
                  # namespace(currently not working, and gives me error 
                  # mentioned above)

  def login
    #loads of logic
  end
end

MyLists.rb文件(我在其中定义模块)与fb_controller.rb位于同一目录中。

如何让命名空间指向fb_controller内部的模块,例如/ api / fb / my_lists?

2 个答案:

答案 0 :(得分:9)

您设置的命名空间正在寻找看起来像这样的控制器类

class Api::Fb::MyListsController

如果您希望路线看起来像/api/fb/my_lists,但您仍希望使用FbController而不是MyListsController,则需要将路线设置为这样

namespace :api do
  scope "/fb" do
    resources :my_lists, :controller => 'fb'
  end
end

在我看来,您MyLists中的模块FbController似乎并不那么尴尬。

我可能会做的是有一个带有通用FbController的模块FB然后有MyListsController < FbController。无论如何,这超出了你的问题的范围。

以上内容应该满足您的需求。

修改

从您的评论和我对您尝试做的事情的假设是一个小例子:

<强>配置/ routes.rb中

namespace :api do
  scope "/fb" do
    post "login" => "fb#login"
    # some fb controller specific routes
    resources :my_lists
  end
end

<强> API / FB / fb_controller.rb

class Api::FbController < ApiController
  # some facebook specific logic like authorization and such.
  def login
  end
end

<强> API / FB / my_lists_controller.rb

class Api::MyListsController < Api::FbController
  def create
    # Here the controller should gather the parameters and call the model's create
  end
end

现在,如果您只想创建一个MyList对象,那么您可以直接对模型执行逻辑。另一方面,如果您想要处理更多逻辑,那么您希望将该逻辑放在一个服务对象中,该服务对象处理MyList及其关联的Wishes或您的MyList模型的创建。我可能会去服务对象。请注意,服务对象应该是类而不是模块。

答案 1 :(得分:1)

在您的示例中,Fb不是命名空间,而是控制器。命名空间调用正在强制您的应用查找不存在的Fb模块。尝试设置这样的路线:

namespace :api do
  resource :fb do
    post :login
    resources :my_lists do
      resources :my_wishes
    end
  end
end

您可以选择为API命名空间定义新的基本控制器:

# app/controllers/api/base_controller.rb
class Api::BaseController < ApplicationController
end

如果您这样做,您的其他控制器可以继承:

# app/controllers/api/fb_controller.rb
class Api::FbController < Api::BaseController
end

运行rake routes可以让您了解其他控制器的布局方式。只是一个警告 - 通常不建议将资源嵌套超过1深(你将最终得到像edit_api_fb_my_list_my_wish_path这样的复杂路径)。如果您能够以更简单的方式构建它,那么您可能会有更轻松的时间。