【问题标题】:Rails Routing Error: Uninitialized Constant with Nested ResourcesRails 路由错误:嵌套资源的未初始化常量
【发布时间】:2021-10-04 17:38:48
【问题描述】:

由于 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.rb 位于app/controllers/users 文件夹下

def show
end

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

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

更新:问题已解决,如果你有同样的问题,请参考下面的cmets(我根据自己的理解进行了总结,但不确定是否完全正确)!或者查看下面的答案,因为工程师mnky 和 ​​Scott 的答案都应该有效。

【问题讨论】:

  • 您的TasksController 是否在适当的命名空间中?它不仅是文件位置 (afaik),而且文件的内容也需要在 Users 命名空间中。请尝试并返回。
  • 您不应该在 app/controllers/users 下拥有 tasks_controller,因为“users”不是命名空间。更多信息,guides.rubyonrails.org/…
  • @VijayRaghavanAravamudhan 是的,我确实使用过class Users::TasksController < ApplicationController
  • @razvans 但是,除非我将 tasks_controller.rb 放在用户文件夹下,否则我自定义的任务操作将不起作用。我应该怎么做才能使自定义动作和自动生成的动作都起作用?
  • @razvans 哦,我把自定义动作的路线从嵌套的资源中分离出来了,它可以工作。感谢您的帮助!

标签: ruby-on-rails ruby nested-routes


【解决方案1】:

关键是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 对象处理。

【讨论】:

  • 我明白了,谢谢!但是我应该如何使用嵌套资源在 routes.rb 中为我的自定义操作编写路由器?
  • 我尝试在嵌套资源之外写,效果很好,不知道这是否是正确的方法?
  • 您的嵌套自定义方法应该为自己定义一个路径,但您将使用to: 参数覆盖它。我会删除它,运行 rails routes 看看它为你创造了什么,然后从那里开始。
【解决方案2】:

您的问题是 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

【讨论】:

  • 非常感谢,这也应该是一个答案!可惜只能接受一个答案。
  • @hcww 无需遗憾。如果这个答案无论如何有帮助,你可以投票,或者它可能会帮助其他人在未来偶然发现这个问题(这就是 SO 的全部意义)
【解决方案3】:

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

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

【讨论】:

  • 感谢您的回答,但是使用嵌套资源是可以的,如果您想知道如何解决问题,请参考上面的答案。:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多