为什么尝试使用Grape with Rails失败了"未初始化的常量API"?

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.


Ros*_*han 5

从葡萄的文档:

对于大于 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)