2016-07-24 39 views
2

我正在將Devise Token Auth整合到我的版本爲的Rails 5 API中。下面是結構:設計令牌認證 - 版本化API:未初始化的常量ApplicationController

的Gemfile

source 'https://rubygems.org' 
... 
gem 'omniauth', '~> 1.3' 
gem 'devise_token_auth', '~> 0.1.38' 
... 

的routes.rb

require "api_constraints" 

Rails.application.routes.draw do 

    namespace :api, defaults: { format: :json } do 
    scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do 
     mount_devise_token_auth_for 'User', at: 'auth' 
     resources :users 
    end 
    end 
end 

application_controller.rb(APP /控制器/ API/V1 /)

module Api 
    module V1 
    class ApplicationController < ActionController::API 
     include ActionController::Serialization 
     include DeviseTokenAuth::Concerns::SetUserByToken 
    end 
    end 
end 

當我嘗試POST:

{ 
    "email": "[email protected]", 
    "password": "testuserpassword" 
} 

/api/auth/sign_in,我得到的錯誤ActionController::RoutingError (uninitialized constant ApplicationController)

看起來devise_controller在嘗試調用自己的方法時無法訪問ApplicationController。於是,我嘗試設置基本控制器:

mount_devise_token_auth_for 'User', at: 'auth', base_controller: 'Api::V1::ApplicationController'

這也沒有工作。

要解決這個問題,我可以刪除module分離,application_controller.rb使其:

class ApplicationController < ActionController::API 
    include ActionController::Serialization 
    include DeviseTokenAuth::Concerns::SetUserByToken 
end 

但當然會導致不同的負載誤差(因爲事情不再作用域正確):LoadError (Unable to autoload constant Api::V1::ApplicationController, expected /home/ubuntu/workspace/app/controllers/api/v1/application_controller.rb to define it)

,實際工作是沒有它命名空間/模塊中的作用域在所有的唯一的事:

Rails.application.routes.draw do 

    mount_devise_token_auth_for 'User', at: 'auth' 

    namespace :api, defaults: { format: :json } do 
    scope module: :v1, 
        constraints: ApiConstraints.new(version: 1, default: true) do 
     resources :users 
    end 
    end 
end 

但失敗版本的整個目的。我錯過了什麼嗎?

回答

3

我沒有花哨的默認作用域發生,但這個工作對我來說:

Rails.application.routes.draw do 
    namespace :api do 
    scope :v1 do 
     mount_devise_token_auth_for 'User', at: 'auth' 
    end 
    end 
end 

一個很大的區別是,除了我的正常範圍的,由版本ApplicationController中,我有一個在ApplicationController的app/controller/application_controller.rb,上面寫着:

class ApplicationController < ActionController::API 
    include DeviseTokenAuth::Concerns::SetUserByToken 
end 

這可能不是很理想,但它與DeviseTokenAuth目前是如何設計的作品。適當的修復可能會涉及到DeviseTokenAuth本身內部的更改。

希望這是有幫助的。與上面的代碼,我有工作做什麼,我需要做以下路線:

api_user_session POST /api/v1/auth/sign_in(.:format) devise_token_auth/sessions#create

。 。 。當您嘗試類似的解決方案時,我沒有看到您提到的「不同的負載錯誤」。

+0

感謝您的回答!我現在在工作,所以我無法測試這個,但我會在幾個小時之內。 –

+2

這樣做的伎倆,雖然我覺得我已經嘗試過......我猜不是!如果您的API實際上有多個版本,則需要將範圍:'scope:v1,as::v1'以避免出現錯誤:'無效的路由名稱已被使用:'new_api_user_session'' 。這些版本也可以是命名空間而不是範圍的,這可以解決這個問題,但是這似乎使整體結構不夠靈活。 –

0

設計試圖使其內置控制器繼承自己的ApplicationController,但在你的應用程序中,該類不存在。相反,你有一個Api::V1::ApplicationController類。

幸運的是,你可以將Devise配置爲從別的東西繼承。在您的config/initializers/devise.rb中,執行此操作:

config.parent_controller = 'Api::V1::ApplicationController' 
+0

感謝您的回答Paul,但是這打破了版本控制的目的,因爲只有一個API版本可以擁有正確的父控制器。 –

相關問題