kno*_*ody 1 ruby api ruby-on-rails ruby-grape ruby-on-rails-4
我希望有人解释为什么在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
Run Code Online (Sandbox Code Playgroud)
app/api/v1/root.rb:
module API::V1
class Root < Grape::API
version 'v1'
mount API::V1::Users
end
end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
config/routes.rb:
Rails.application.routes.draw do
mount API::Root => '/'
end
Run Code Online (Sandbox Code Playgroud)
在我的application.rb添加中:
config.paths.add "app/api", glob: "**/*.rb"
config.autoload_paths += Dir["#{Rails.root}/app/api/*"]
Run Code Online (Sandbox Code Playgroud)
在那种情况下,我收到错误: NameError: uninitialized constant API
但如果我的代码如下:
app/api/root.rb 与上述相同
然后app/api/v1/root.rb:
class Root < Grape::API
version 'v1'
mount Users
end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
config/routes.rb:
Rails.application.routes.draw do
mount Root => '/'
end
Run Code Online (Sandbox Code Playgroud)
和config/application.rb上面一样
一切正常.
我的问题是,为什么没有我需要里面指定的模块v1/root.rb内,也v1/users还我为什么不需要使用API::Root => '/'的config/routes.rb?
小智 8
这是因为它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.
从葡萄的文档:
对于大于 6.0.0.beta2 的 Rails 版本,Zeitwerk自动加载器是 CRuby 的默认设置。默认情况下Zeitwerk变形api为 asApi而不是API。为了使我们的示例工作,您需要取消注释底部的行config/initializers/inflections.rb,并添加API为首字母缩写词:
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'API'
end
Run Code Online (Sandbox Code Playgroud)