尝试实现password_reset Railscast时语句无效

时间:2012-01-26 06:02:32

标签: ruby-on-rails-3 passwords password-recovery

我正在尝试在我的应用中实施Railscast #274,因此我可以提供密码重置选项。我已经到了可以将电子邮件键入密码重置表单的位置,并收到一封电子邮件,其中包含重置密码的链接。当我输入新密码并尝试保存时,事情开始出错。我最后得到了Action Controller:Exception caught。以下是我使用password_reset链接发送电子邮件后,我的日志显示的内容:

Started GET "/password_resets/new" for 127.0.0.1 at 2012-01-26 00:50:42 -0500
  Processing by PasswordResetsController#new as HTML

点击password_reset链接:

Started GET "/password_resets/qlslPnuOhdyMCNseMnV3bA/edit" for 127.0.0.1 at 2012-01-26 00:51:08 -0500
  Processing by PasswordResetsController#edit as HTML
  Parameters: {"id"=>"qlslPnuOhdyMCNseMnV3bA"}

添加新密码和:password_confirmation会产生错误:

Started POST "/password_resets/qlslPnuOhdyMCNseMnV3bA" for 127.0.0.1 at 2012-01-26 00:53:08 -0500
  Processing by PasswordResetsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"2egfT2lr35FhuVPWDB72vcS2zPlqC75tcyctRp61ZHw=", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "commit"=>"Update Password", "id"=>"qlslPnuOhdyMCNseMnV3bA"}

Started GET "/profiles/qlslPnuOhdyMCNseMnV3bA" for 127.0.0.1 at 2012-01-26 00:53:09 -0500
  Processing by ProfilesController#show as HTML
  Parameters: {"id"=>"qlslPnuOhdyMCNseMnV3bA"}

  Profile Load (0.9ms)  SELECT "profiles".* FROM "profiles" WHERE "profiles"."id" = 'qlslPnuOhdyMCNseMnV3bA' LIMIT 1
PGError: ERROR:  invalid input syntax for integer: "qlslPnuOhdyMCNseMnV3bA"
LINE 1: ...ofiles".* FROM "profiles" WHERE "profiles"."id" = 'qlslPnuOh...
                                                             ^
: SELECT  "profiles".* FROM "profiles" WHERE "profiles"."id" = 'qlslPnuOhdyMCNseMnV3bA' LIMIT 1
Completed   in 57ms

ActiveRecord::StatementInvalid (PGError: ERROR:  invalid input syntax for integer: "qlslPnuOhdyMCNseMnV3bA"
LINE 1: ...ofiles".* FROM "profiles" WHERE "profiles"."id" = 'qlslPnuOh...
                                                         ^
: SELECT  "profiles".* FROM "profiles" WHERE "profiles"."id" = 'qlslPnuOhdyMCNseMnV3bA' LIMIT 1):
  app/controllers/profiles_controller.rb:41:in `show'

在profiles_controller.rb中:show中的41:

def show
  @profile = Profile.find(params[:id])
  @user = User.find(@profile.user_id)
  ..
end

在执行此操作之前,我将数据库转储,运行rake:db create,然后rake:db migrate,然后再重新播种数据库。这可能是因为我没有运行脚本给现有用户一个password_reset_token?

更新:包括password_resets_controller.rb

class PasswordResetsController< ApplicationController的       def new       端

  def create
    @user = @User.find_by_email(params[:email])
    if user
      user.send_password_reset
      redirect_to new_password_reset_path, :notice => "Check your email for password reset instructions."
    else
      redirect_to new_password_reset_path, :notice => "Sorry, we couldn't find that email. Please try again."
    end
  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.password_reset_sent_at < 2.hours.ago
      redirect_to new_password_reset_path, :alert => "Your password reset link has expired."
    elsif @user.update_attributes(params[:user])
      redirect_to profile_path, :notice => "Great news: Your password has been reset."
    else
      render :edit
    end
  end
end

1 个答案:

答案 0 :(得分:1)

问题出现在PasswordResetsController#update

def update
  @user = User.find_by_password_reset_token!(params[:id])
  if @user.password_reset_sent_at < 2.hours.ago
    redirect_to new_password_reset_path, :alert => "Your password reset link has expired."
  elsif @user.update_attributes(params[:user])
    redirect_to profile_path, :notice => "Great news: Your password has been reset."
  else
    render :edit
  end
end

特别是redirect_to profile_path

如果查看日志,您会看到以下序列:

POST "/password_resets/qlslPnuOhdyMCNseMnV3bA"
GET  "/profiles/qlslPnuOhdyMCNseMnV3bA"

,路线应为/password_resets/:id/profiles/:id/password_resets想要'qlslPnuOhdyMCNseMnV3bA'令牌,但/profiles想要用户的数字ID。

回到控制器,我们看到了:

redirect_to profile_path, :notice => "Great news: Your password has been reset."

您没有告诉profile_path要使用哪个用户,因此显然抓住params[:id]来构建错误的/profiles/qlslPnuOhdyMCNseMnV3bA网址。尝试告诉profile_path使用哪个用户:

redirect_to profile_path(@user), :notice => "Great news: Your password has been reset."