【问题标题】:Why does Devise creates incorrect lost password POST path with custom route为什么 Devise 使用自定义路由创建不正确的丢失密码 POST 路径
【发布时间】:2015-03-08 15:55:48
【问题描述】:

我有一个简单的用户模型的简单设计安装。我用默认路由确认一切正常(注册、丢失密码等),然后开始像这样自定义:

  devise_for :users, :skip => [:sessions, :registrations, :passwords]
  as :user do

     get 'signin' => 'devise/sessions#new', :as => :new_user_session
     post 'signin' => 'devise/sessions#create', :as => :user_session
     delete 'signout' => 'devise/sessions#destroy', :as => :destroy_user_session

     get 'register/cancel' => 'devise/registrations#cancel', :as => :cancel_user_registration
     post 'register' => 'devise/registrations#create', :as => :user_registration
     get 'register' => 'devise/registrations#new', :as => :new_user_registration
     get 'account' => 'devise/registrations#edit', :as => :edit_user_registration
     patch 'account' => 'devise/registrations#update'
     put 'account' => 'devise/registrations#update'
     delete 'account' => 'devise/registrations#destroy'

     post 'password' => 'devise/passwords#create', :as => :user_password
     get 'password/forgot' => 'devise/passwords#new', :as => :new_user_password
     get 'password/reset' => 'devise/passwords#edit', :as  => :edit_user_password
     patch 'password' => 'devise/passwords#update'
     put 'password' => 'devise/passwords#update'

  end

然而,忘记密码页面会创建一个如下所示的 POST 路径:

<form class="new_user" id="new_user" action="/password.user" accept-charset="UTF-8" method="post">
...
</form>

从相应的观点来看:

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>

使用默认设计路由,url 正确显示为/users/password,但使用我的自定义路由,我得到/password.user。好像只有这一条路。

我知道简单的解决方法是将password_path(resource_name) 更改为password_path,但我想了解为什么这首先会中断。

【问题讨论】:

    标签: ruby-on-rails devise routes


    【解决方案1】:

    在深入研究了 Devise 的来源并进行了一些实验之后,我想我已经找到了发生这种情况的原因。如果您查看devise_for 为模型:user 生成的路由,则密码路由具有前缀user_password。路由方法是user_password_path。那么password_path 实际上是如何工作的呢?

    new.html.erb中调用的password_path方法实际上并不是devise_for :user生成的方法。它是一个辅助方法,将模型的名称作为参数。例如,当通过:user 时,它将如下所示:

    password_path(:user) => user_password_path
    

    这个方法然后调用user_password_path,这是正确的。更多信息here

    在您的情况下,您正在创建一个前缀为 user_password 的路由,但您也有这些路由:

     patch 'password' => 'devise/passwords#update'
     put 'password' => 'devise/passwords#update'
    

    生成带有前缀password 的路由。我猜这会覆盖/优先于UrlHelper 中的password_path 方法。

    关于它返回/password.user的原因,每个路由方法都采用一个可选的格式参数来指定请求的格式(例如/password.html/password.json等)。在您的情况下,resource_name 的值是 user

    你能做什么?我建议您将putpatch 方法与:edit_user_password 前缀相关联,保持与devise 生成的路由相同的结构。这样您就不会覆盖/隐藏在设计的UrlHelper 中定义的password_path 方法。

    注意:在尝试路由时,我不得不在某些时候重新启动服务器。因此,如果某些事情没有按预期发生,请尝试重新启动它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 1970-01-01
      • 2019-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多