【问题标题】:Custom Devise routes自定义设计路线
【发布时间】:2014-01-22 18:19:29
【问题描述】:
Using devise (3.2.2)
Using rails (4.0.2)

致力于开发只需要某些路由的 API。我的routes.rb 中有以下内容:

devise_for :users, path: '/users', controllers: {
  sessions: 'v1/custom_devise/sessions',
  passwords: 'v1/custom_devise/passwords'
}

太棒了!现在我们有了所有这些路线:

              Prefix Verb    URI Pattern                    Controller#Action
    new_user_session GET     /users/sign_in(.:format)       v1/custom_devise/sessions#new
        user_session POST    /users/sign_in(.:format)       v1/custom_devise/sessions#create
destroy_user_session DELETE  /users/sign_out(.:format)      v1/custom_devise/sessions#destroy
       user_password POST    /users/password(.:format)      v1/custom_devise/passwords#create
   new_user_password GET     /users/password/new(.:format)  v1/custom_devise/passwords#new
  edit_user_password GET     /users/password/edit(.:format) v1/custom_devise/passwords#edit
                     PATCH   /users/password(.:format)      v1/custom_devise/passwords#update
                     PUT     /users/password(.:format)      v1/custom_devise/passwords#update

但我不想要或不需要这些路线:

    new_user_session GET     /users/sign_in(.:format)       v1/custom_devise/sessions#new
   new_user_password GET     /users/password/new(.:format)  v1/custom_devise/passwords#new
  edit_user_password GET     /users/password/edit(.:format) v1/custom_devise/passwords#edit

所以我想我会按照文档创建自己的路线。于是我换了routes.rb

devise_scope :user do
  post   '/users/sign_in'  => 'custom_devise/sessions#create',  as: :user_session
  delete '/users/sign_out' => 'custom_devise/sessions#destroy', as: :destroy_user_session

  post  '/users/password'  => 'custom_devise/passwords#create', as: :user_password
  put   '/users/password'  => 'custom_devise/passwords#update', as: nil
  patch '/users/password'  => 'custom_devise/passwords#update', as: nil
end

现在我的路线看起来很完美,就像我想要的那样:

              Prefix Verb    URI Pattern                   Controller#Action
        user_session POST    /users/sign_in(.:format)      v1/custom_devise/sessions#create
destroy_user_session DELETE  /users/sign_out(.:format)     v1/custom_devise/sessions#destroy
       user_password POST    /users/password(.:format)     v1/custom_devise/passwords#create
                     PUT     /users/password(.:format)     v1/custom_devise/passwords#update
                     PATCH   /users/password(.:format)     v1/custom_devise/passwords#update

但现在我的请求失败了:

 AbstractController::ActionNotFound:
   Could not find devise mapping for path "/users/sign_in".
   This may happen for two reasons:

   1) You forgot to wrap your route inside the scope block. For example:

     devise_scope :user do
       get "/some/route" => "some_devise_controller"
     end

   2) You are testing a Devise controller bypassing the router.
      If so, you can explicitly tell Devise which mapping to use:

      @request.env["devise.mapping"] = Devise.mappings[:user]

我尝试了很多变化,但无济于事。

更新:这可能有点矫枉过正,但这里有一个示例应用程序演示了这一点。不确定我做错了什么,或者这可能是一个设计错误。

示例应用:https://github.com/michaelirey/devise_weird

【问题讨论】:

  • "/users/sign_in" 用于设计新会话,因此您将需要 new_user_session 路由。
  • @CharlesJHardy:不需要对/users/sign_inGET 请求,因为这是一个API。
  • 这些故障是发生在测试中还是在开发中?
  • @LouisSimoneau:发展
  • 我克隆了示例应用,它运行良好。

标签: ruby-on-rails ruby api devise routes


【解决方案1】:

您缺少显示登录表单的登录操作的 GET。您只有会话创建,像这样修复它(您:

devise_scope :user do
  get   '/users/sign_in'  => 'custom_devise/sessions#new',  as: :new_user_session      
  post   '/users/sign_in'  => 'custom_devise/sessions#create',  as: :user_session
  delete '/users/sign_out' => 'custom_devise/sessions#destroy', as: :destroy_user_session

  post  '/users/password'  => 'custom_devise/passwords#create', as: :user_password
  put   '/users/password'  => 'custom_devise/passwords#update', as: nil
  patch '/users/password'  => 'custom_devise/passwords#update', as: nil
end

【讨论】:

  • 不确定这是否回答了发布的问题,但绝对帮助我解决了让我进入此页面的问题。谢谢!
【解决方案2】:

顺便说一句,与这个问题分开,OP 在这个问题上得到了移动: https://github.com/plataformatec/devise/issues/2840

这可以解释为什么它在 2014 年 1 月失败后于 2014 年 8 月奏效。

线程的关闭 cmets 是:

这应该对 2016 年的任何人都有帮助 http://stackoverflow.com/questions/22063026/how-do-i-override-devise-controller-and-devise-routes-at-the-same-time

还有:

任何人即使在这样做后仍然面临这个问题

devise_for :users, skip: :all devise_scope :user do end

如果您来电,请参考此问题#2496 命名空间内的 devise_scope。

【讨论】:

    【解决方案3】:

    这是我如何解决这个问题的工作示例:

    Rails.application.routes.draw do
    
      # This is the fix.
      devise_for :users, skip: :all
    
      devise_scope :user do
        get "/users/sign_in", to: "devise/sessions#new", as: :new_user_session
        post "/users/sign_in", to: "devise/sessions#create", as: :user_session
        delete "/users/sign_out", to: "devise/sessions#destroy", as: :destroy_user_session
        get "/users/password/new", to: "devise/passwords#new", as: :new_user_password
        get "/users/password/edit", to: "devise/passwords#edit", as: :edit_user_password
    
        patch "/users/password", to: "devise/passwords#update", as: :user_password
        put "/users/password", to: "devise/passwords#update"
        post "/users/password", to: "devise/passwords#create"
    
        get "/users/cancel", to: "devise/registrations#cancel", as: :cancel_user_registration
        get "/users/sign_up", to: "devise/registrations#new", as: :new_user_registration
        get "/users/edit", to: "devise/registrations#edit", as: :edit_user_registration
    
        patch "/users", to: "devise/registrations#update", as: :user_registration
        put "/users", to: "devise/registrations#update"
        delete "/users", to: "devise/registrations#destroy"
        post "/users", to: "devise/registrations#create"
      end
    end
    

    感谢您的提示,GuyPaddock。想我会将此作为单独的答案发布,因为您的答案没有完整的代码示例,也没有明确说明这是一个解决方案。

    【讨论】:

      猜你喜欢
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-04
      • 1970-01-01
      相关资源
      最近更新 更多