为什么尝试使用Grape with Rails失败了“未初始化的常量API”?
我希望有人解释为什么在Rails(4.1.8)和Grape(0.10.1)中发生这种情况
所以这是我的API:
app/api/root.rb
:
module API class Root < Grape::API prefix 'api' mount API::V1::Root end end
app/api/v1/root.rb
:
module API::V1 class Root < Grape::API version 'v1' mount API::V1::Users end end
app/api/v1/users.rb
:
module API::V1 class Users < Grape::API format 'json' resource :users do desc "Return list of users" get '/' do User.all end end end end
config/routes.rb
:
Rails.application.routes.draw do mount API::Root => '/' end
在我的application.rb
我添加了:
config.paths.add "app/api", glob: "**/*.rb" config.autoload_paths += Dir["#{Rails.root}/app/api/*"]
在这种情况下,我得到错误: NameError: uninitialized constant API
但如果我的代码如下:
app/api/root.rb
与上面相同
然后app/api/v1/root.rb
:
class Root < Grape::API version 'v1' mount Users end
app/api/v1/users.rb
:
class Users < Grape::API format 'json' resource :users do desc "Return list of users" get '/' do User.all end end end
config/routes.rb
:
Rails.application.routes.draw do mount Root => '/' end
和config/application.rb
一样
一切正常。
我的问题是为什么我不需要在v1/root.rb
内部以及v1/users
内部指定模块,以及为什么我不需要在config/routes.rb
使用API::Root => '/'
?
这是因为app/api
是API类的顶级文件夹,而不是app
。
来自Grape的文档 :
将API文件放入
app/api
。 Rails需要一个与Ruby模块名称匹配的子目录和一个与该类名称匹配的文件名。 在我们的示例中,Twitter::API
的文件名位置和目录应为app/api/twitter/api.rb
因此, API::Root
类的正确位置实际上是app/api/api/root.rb
,而不是/app/api/root.rb
尽管这是顶级命名空间中类的正确位置,这就是你给出的第二个例子(从API
模块中删除了类)的原因。
我建议您将API类保存在自己的模块中,然后将它们移动到app/api
下面的匹配子文件夹中。
我试着将我的文件放到app/api/api
,但它对我不起作用。
我只需将api
文件夹放入controller
文件夹即可找到解决方案。 我不是100%确定问题是什么,但我的猜测是它与自动加载的路径有关。