Why does mounting a route in Rails fail with "uninitialized constant API"?
Asked Answered
R

1

7

I am working on an app that includes an API that is using the grape gem.

Here is my Root Class:

module API
  class Root < Grape::API
    rescue_from :all do |e|
      Rack::Response.new(
        [ "Error: #{e.message}" ],
        500,
        { "Content-type" => "text/error" }
      ).finish
    end

    prefix "api"
    version 'v1', using: :path
    format :json
    error_format :json

    mount ::API::ServiceRequests
  end
end

Here is how I am mounting it in routes:

mount API::Root => '/'

The error I am receiving is: routes.rb:45:inblock in ': uninitialized constant API (NameError)`

The files are structured like app/api/root.rb and I have this bit of code in my application.rb to load in the files:

config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
Ringdove answered 18/7, 2014 at 20:17 Comment(0)
G
15

Try moving your API code's files from app/api to app/api/api.

From Grape's documentation:

Place API files into app/api. Rails expects a subdirectory that matches the name of the Ruby module and a file name that matches the name of the class. In our example, the file name location and directory for Twitter::API should be app/api/twitter/api.rb.

Thus the correct location for your API::Root class would actually be app/api/api/root.rb.

Gastric answered 18/7, 2014 at 20:38 Comment(1)
I have been scratching my head for a day around the same issue as OP, thanks for the answer! I had app/api/v1/my_endpoint prefixed as API::V1::MyEndpoint. Moving it to app/api/api/v1/my_endpoint solved my problem. This seems pretty srange to me, but I guess this shows I should give a more specific name to the api, like app/api/github/v1/my_endpoint or app/api/google/v1/my_endpoint, etc.Densmore

© 2022 - 2024 — McMap. All rights reserved.