2015-01-23 3 views
1

Я хотел бы кто-то объяснить, почему это происходит в Rails (4.1.8) с виноградом (0.10.1)Почему попытка использовать Grape with Rails не работает с «неинициализированным постоянным API»?

это мой 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 и почему мне не нужно использовать API::Root => '/' в config/routes.rb?

ответ

7

Это потому, что app/api является папкой верхнего уровня для ваших классов API, а не app.

От 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 .

Поэтому правильное место для API::Root класса фактически будет app/api/api/root.rb, не /app/api/root.rb — хотя это является правильного расположения для класса в пространстве имен верхнего уровня, который почему второй пример, который вы даете (с классами, удаленными из модуля API), работает.

Я рекомендую вам держать свои классы API вместе в своем собственном модуле и перемещать их в соответствующую подпапку под app/api.

+0

спасибо, что имеет смысл. Я видел подобный ответ на какой-то другой вопрос, но он не дошел до меня. это все понятно и имеет смысл. Спасибо @Simon – knowbody

0

Я попытался поместить свои файлы в app/api/api, но он не работал для меня.

Я нашел решение, просто разместив папку api в папке controller. Я не уверен, что проблема была на 100%, но я предполагаю, что она имеет какое-то отношение к автозагруженным путям.

+0

проверить ответ @ Саймона выше. Причина также цитируется выше. решил мои проблемы – knowbody

+0

Я знаю, но я документировал свое решение для кого-то еще, кто столкнется с той же проблемой и не сможет решить проблему с ответом Саймона. – zhurora

 Смежные вопросы

  • Нет связанных вопросов^_^