嵌套控制器中的未初始化常量错误

3
我正在遇到这个错误:
Routing Error
uninitialized constant RegistrationsController

这是我的日志:
Started GET "/registrants/1/registrations/new" for 127.0.0.1 at 2012-07-03 00:55:44 -0500

ActionController::RoutingError (uninitialized constant RegistrationsController):

Rendered /.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.1.3/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (8.5ms)

这是我routes.rb文件的相关部分:

这是适当的部分:

registrant_registrations GET    /registrants/:registrant_id/registrations(.:format)          {:action=>"index", :controller=>"registrations"}
                                   POST   /registrants/:registrant_id/registrations(.:format)          {:action=>"create", :controller=>"registrations"}
       new_registrant_registration GET    /registrants/:registrant_id/registrations/new(.:format)      {:action=>"new", :controller=>"registrations"}
      edit_registrant_registration GET    /registrants/:registrant_id/registrations/:id/edit(.:format) {:action=>"edit", :controller=>"registrations"}
           registrant_registration GET    /registrants/:registrant_id/registrations/:id(.:format)      {:action=>"show", :controller=>"registrations"}
                                   PUT    /registrants/:registrant_id/registrations/:id(.:format)      {:action=>"update", :controller=>"registrations"}

这是我的注册控制器,位于/app/controllers/portal/registrations_controller.rb

class Portal::RegistrationsController < ApplicationController
  def create
        @registrant = current_member.registrants.find(params[:registrant])
        @registration = @registrant.registrations.build

        respond_to do |format|
          if @registration.save
            format.html {   redirect_to root_path, :notice => "Registration successfully created!" }
            format.json { head :ok }
          else
           format.html { redirect_to root_path, :notice => "There was a problem with the registration." }
          end
        end     
  end

end

当我在Portal#index的视图中调用new_registrant_registration_path(registrant)时,会出现此错误。

编辑:

为了完整起见,在找到解决方案之前,这里是我的routes.rb文件的全部内容。Radar提到了我发布的gist,但我想把代码放在这里,以防那个gist被删除。

MyApp::Application.routes.draw do

  match 'admin' => 'admin/dashboard#index', :as => :admin_root
  match 'portal' => 'portal#index', :as => :member_root

  namespace 'admin' do
    match 'profile' => 'profile#show', :as => :profile

    resources :members
    resources :admins
        resources :packages
        resources :products
        resources :levels
        resources :lessons
        resources :registrations
        resources :registrants, :controller => 'customers/registrants'
        resources :locations
        resources :schools
        resources :terms
        resources :customers
        resources :invoices
        resources :payments
  end

  namespace 'member' do
    resources :registrations
  end

  match 'register' => 'member/registrations#new', :as => :signup  
  match 'login' => 'member_sessions#new', :as => :login
  match 'logout' => 'member_sessions#destroy', :as => :logout  
  match 'admin/login' => 'admin_sessions#new', :as => :admin_login
  match 'admin/logout' => 'admin_sessions#destroy', :as => :admin_logout

  match 'member/activate/:activation_code' => 'member/activations#create', :as => :member_activation
  match 'member/:id/activate/resend' => 'member/activations#resend', :as => :resend_member_activation
  match 'member/:id/activate' => 'member/activations#new', :as => :new_member_activation

  match 'member/password/reset/begin' => 'member/password_resets#new', :as => :new_member_password_reset, :via => :get
  match 'member/password/reset' => 'member/password_resets#create', :as => :member_password_resets, :via => :post
  match 'member/password/:token/finish' => 'member/password_resets#edit', :as => :edit_member_password_reset, :via => :get
  match 'member/password/reset' => 'member/password_resets#update', :as => :member_password_reset, :via => :put

  match 'admin/packages/new/:partial' => 'admin/packages#new'

  resources :admins

  resources :registrants, :controller => 'portal/registrants' do
    resources :registrations
  end

  resource :admin_session
  resource :member_session

  root :to => 'portal#index'

end

你能把负责注册者注册路由的routes.rb文件中实际部分放在这里吗? - melekes
3个回答

11
为了让事情更清楚:marcamillion进入了Freenode的#rubyonrails并分享了他的config/routes.rb。那时我发现了他犯的错误,然后找到了答案。

两件事情。

第一:管理员根路由

与其像这样定义您的admin命名空间的根路由:

match 'admin' => 'admin/dashboard#index', :as => :admin_root

namespace :admin中定义如下:

namespace 'admin' do
  root :to => "dashboard#index"
end

这将自动定义它为admin_root_pathadmin_root_url,因此您不需要这样做,并且它将自动在控制器前缀中添加admin/前缀,因此您也不需要这样做。
第二步:引用RegistrantsController 您目前在config/routes.rb中有这个内容:
resources :registrants, :controller => 'portal/registrants' do
  resources :registrations
end

这将使用Portal::RegistrantsController正确定义registrants资源路由,但不会使用Portal::RegistrationsController定义其下的嵌套路由。它将尝试使用RegistrationsController,这就是为什么你会得到那个错误提示的原因。
为了解决这个问题,我建议你使用scope方法,像这样:
scope :module => Portal do
 resources :registrants do
  resources :registrations
 end
end

当以这种方式使用scope方法时,它会告诉Rails路由块中的控制器位于Portal命名空间下。这意味着它会知道resources :registrants 是为 Portal::Registrants服务的,resources :registrations 是为 Portal::Registrations服务的,从而解决您看到的错误。


感谢详细的解释...这完全有道理。 - marcamillion
8
不加解释地对这个回答进行踩票会让你看起来像个蠢驴,匿名的懦夫。请注意。 - Ryan Bigg

-2

如果你改变这一行会怎样:

class Portal::RegistrationsController < ApplicationController

to:

class RegistrationsController < ApplicationController

?


2
RegistrationsController 需要放在 Portal 内部,因为它是该命名空间功能的一部分。 - Ryan Bigg

-2
这很奇怪。我认为你的控制器应该位于/app/controllers/registrants/registrations_controller.rb,并且应该长成这样:

class Registrants::RegistrationsController < Registrants::ApplicationController
  def create
    @registration = registrant.registrations.build

    ...
  end
end

class Registrants::ApplicationController < ApplicationController
  def registrant
    current_member.registrants.find(params[:registrant_id])
  end
end

Registrants::ApplicationController (/app/controllers/registrants/application_controller.rb) 控制器的目的是避免代码重复。


我有两个命名空间,它们都以不同的方式处理注册。哦,还有...这个注册不是针对单个用户的。基本上,一个“成员”(在Member命名空间中的用户)拥有许多“注册者”。这些注册者又拥有许多“注册信息”。因此,这个注册与一个特定的注册者相关联,而这个注册者又与一个成员相关联。因此,这个注册控制器就在这里...因为“门户”是一个成员登录后看到的视图。 - marcamillion
解决后果或绕过它们并不等同于解决初始原因。 - Tanel Suurhans
我给你的回答点了踩。这个答案是错误的,也无法解决需要 RegistrantsController 的问题。请看我的回答,了解如何修复它。 - Ryan Bigg
@tanel-suurhans 您是正确的。在回答这个问题之前,我应该先询问routes.rb的位置。 - melekes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接