Rails Routing Error: Uninitialized Constant with Nested Resources

Rails Routing Error: Uninitialized Constant with Nested Resources

由于 rake routes 给出了我访问过的确切路线,页面显示
Routing Error uninitialized constant TasksController Did you mean? AppsController

routes.rb中我写了

  resources :users do 
    resources :tasks do
      collection do
        post 'tasks-info', to: 'users/tasks#tasks_info', format: 'json'
      end
    end
  end

并且 tasks_controller.rbapp/controllers/users 文件夹下

def show
end

show.html.slimapp/views/users/tasks 下 foler
我访问的url是http://localhost:3000/users/1/tasks/1rake routes包括
user_task_path GET /users/:user_id/tasks/:id(.:format) tasks#show

我真的不知道错误来自哪里,非常感谢任何帮助!

Updated: Problem solved and please refer to the comments below if you have the same issue here(I have summarized based on my own understanding, not sure whether it's exactly correct though)! Or see the answers below as engineersmnky's and Scott's answers should both work.

关键是rails routes告诉你的是什么:

user_task_path  GET /users/:user_id/tasks/:id(.:format)  tasks#show

最后一节告诉您它正在 tasks 控制器中寻找 show 方法——也就是说,在控制器层次结构的顶层 TasksController

因此,与其将 TasksController 放置在 app/controllers/users/tasks_controller.rb,不如将其放置在 app/controllers/tasks_controller.rb

当调用 TasksController#show 时,控制器的“嵌套”由包含 :user_id:idparams 对象处理。

您的问题是 resources :tasks 推断 TasksController 但您希望 Users::TasksController 处理这些操作。

Rails提供了处理这种路由的方法ActionDispatch::Routing::Mapper::Scoping#scope

要实现这一点,您所要做的就是使用 scope 方法向您的结构添加另一层,如下所示:

  resources :users do 
    scope module: 'users' do 
      resources :tasks do
        collection do
          post 'tasks-info', to: 'users/tasks#tasks_info', format: 'json'
        end
      end
    end
  end

现在所有到用户任务的嵌套路由都将转到 Users::TasksController,因为我们指定 TaskUsers 模块中。您的路线现在看起来像这样(在 rails routes 输出中):

user_task_path  GET /users/:user_id/tasks/:id(.:format)  users/tasks#show

我假设用户是您存储任务控制器的文件夹,在那种情况下您应该使用不同的密钥而不是使用资源。一次只能有一个资源,我们不能在另一个资源中没有资源。从技术上讲,这表明我们在控制器内部安装了控制器,这是不可能的。

namespace :users do
  resources :tasks do
    collection do
      post 'tasks-info', to: 'users/tasks#tasks_info', format: 'json'
    end
  end
end