在Hartl教程之后为Rails应用程序添加密码重置功能

时间:2013-03-17 19:14:19

标签: ruby-on-rails ruby routes forgot-password

我是RoR的新手,并且一直在研究Hartl教程(这很棒)。我已经成功地完成了第9章(稍微调整一下,因为我的最终目标不是创建一个微博网站)。那时,我决定在我的应用程序中添加一个“记住我”复选框并重置密码功能,所以我跳到了railscast tutorial(正如Hartl所建议的那样)。复选框非常顺利,但我用密码重置部分打了一堵砖墙。这是下一次之后的一个错误。我不得不承认我无法帮助自己并稍微调整一下 - 我尝试使用form_for语法而不是form_tag语法。我已经能够提交电子邮件地址,但后来我收到了No route matches [POST] "/reset_password/new"消息。我花了最近两天在stackoverflow上阅读类似的帖子并尝试了建议,但我似乎无法想出一些有用的东西。请帮忙!

这是细节:

我的密码重置视图位于/app/views/reset_password/new.html.erb

<% provide(:title, 'Reset Password') %>
<h1>Reset Password</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for @user, url: new_reset_password_path do |f| %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.submit "Reset Password", class: "btn btn-large btn-methyl" %>
    <% end %>
  </div>
</div>

我的控制器位于/app/controllers/reset_password_controller.rb

class ResetPasswordController < ApplicationController

  def new
    @user = User.new
  end

  def show
  end

  def create
    @user = User.find_by_email(params[:email].downcase)
    user.send_password_reset if user
    redirect_to root_path, notice: "Email sent with password reset instructions."
  end

  def edit
    @user = User.find_by_password_reset_token!(params[:id])
  end

  def update
    @user = User.find_by_password_reset_token!(params[:id])
    if @user.reset_password_sent_at < 2.hours.ago
      redirect_to_new password_reset_path, alert: "Reset password request has expired."
    elsif @user.update_attributes(params[:user])
      redirect_to root_path, notice: "Password has been reset!"
    else
      render :edit
    end
  end
end

我的路线位于/config/routes.rb

Methylme::Application.routes.draw do

  resources :users
  resources :sessions, only: [:new, :create, :destroy]
  resources :reset_password

  root to: 'static_pages#home'

  match '/signup', to: 'users#new'
  match '/signin',  to: 'sessions#new'
  match '/signout', to: 'sessions#destroy', via: :delete

  match '/help', to: 'static_pages#help'
  match '/about', to: 'static_pages#about'
  match '/contact', to: 'static_pages#contact'
.
.
.
end

最后,$ rake routes报告以下内容:

               users GET    /users(.:format)                   users#index
                     POST   /users(.:format)                   users#create
            new_user GET    /users/new(.:format)               users#new
           edit_user GET    /users/:id/edit(.:format)          users#edit
                user GET    /users/:id(.:format)               users#show
                     PUT    /users/:id(.:format)               users#update
                     DELETE /users/:id(.:format)               users#destroy
            sessions POST   /sessions(.:format)                sessions#create
         new_session GET    /sessions/new(.:format)            sessions#new
             session DELETE /sessions/:id(.:format)            sessions#destroy
reset_password_index GET    /reset_password(.:format)          reset_password#index
                     POST   /reset_password(.:format)          reset_password#create
  new_reset_password GET    /reset_password/new(.:format)      reset_password#new
 edit_reset_password GET    /reset_password/:id/edit(.:format) reset_password#edit
      reset_password GET    /reset_password/:id(.:format)      reset_password#show
                     PUT    /reset_password/:id(.:format)      reset_password#update
                     DELETE /reset_password/:id(.:format)      reset_password#destroy
                root        /                                  static_pages#home
              signup        /signup(.:format)                  users#new
              signin        /signin(.:format)                  sessions#new
             signout DELETE /signout(.:format)                 sessions#destroy
                help        /help(.:format)                    static_pages#help
               about        /about(.:format)                   static_pages#about
             contact        /contact(.:format)                 static_pages#contact

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我认为您不想在密码重置视图中链接到new_reset_password_pathnew),而是reset_password_pathcreate), 发送重置密码电子邮件。

如果您的路线没有达到您的预期(例如,create路线没有关联的xxx_path名称),您应该单独声明它们,

post '/reset_password', to: 'reset_password#create', as: 'send_reset_password' # for example
...

答案 1 :(得分:0)

这是Ryan最好的身份验证教程之一,

http://railscasts.com/episodes/250-authentication-from-scratch-revised