2016-07-02 7 views
1

パスワードリセットに合格するためのテストを取得できません。以下を示します。Michael Hartlパスワードリセットエラー

1) Error: 
PasswordResetsTest#test_password_resets: 
NoMethodError: undefined method `[]' for nil:NilClass 
app/controllers/password_resets_controller.rb:10:in `create' 
test/integration/password_resets_test.rb:14:in `block in <class:PasswordResetsTest>' 

何が原因であるのかわかりません。助けてください。

PasswordResetsController

class PasswordResetsController < ApplicationController 
    before_action :get_user,   only: [:edit, :update] 
    before_action :valid_user,  only: [:edit, :update] 
    before_action :check_expiration, only: [:edit, :update] # Case (1) 

    def new 
    end 

    def create 
    @user = User.find_by(email: params[:password_reset][:email].downcase) 
    if @user 
     @user.create_reset_digest 
     @user.send_password_reset_email 
     flash[:info] = "Email sent with password reset instructions" 
     redirect_to root_url 
    else 
     flash.now[:danger] = "Email address not found" 
     render 'new' 
    end 
    end 

    def edit 
    end 

    def update 
    if params[:user][:password].empty?     # Case (3) 
     @user.errors.add(:password, "can't be empty") 
     render 'edit' 
    elsif @user.update_attributes(user_params)   # Case (4) 
     log_in @user 
     flash[:success] = "Password has been reset." 
     redirect_to @user 
    else 
     render 'edit'          # Case (2) 
    end 
    end 

    private 

    def user_params 
     params.require(:user).permit(:password, :password_confirmation) 
    end 

    # Before filters 

    def get_user 
     @user = User.find_by(email: params[:email]) 
    end 

    # Confirms a valid user. 
    def valid_user 
     unless (@user && @user.activated? && 
       @user.authenticated?(:reset, params[:id])) 
     redirect_to root_url 
     end 
    end 

    # Checks expiration of reset token. 
    def check_expiration 
     if @user.password_reset_expired? 
     flash[:danger] = "Password reset has expired." 
     redirect_to new_password_reset_url 
     end 
    end 
end 

PasswordsResetsTest

require 'test_helper' 

class PasswordResetsTest < ActionDispatch::IntegrationTest 

    def setup 
    ActionMailer::Base.deliveries.clear 
    @user = users(:michael) 
    end 

    test "password resets" do 
    get new_password_reset_path 
    assert_template 'password_resets/new' 
    # Invalid email 
    post password_resets_path, params: { password_reset: { email: "" } } 
    assert_not flash.empty? 
    assert_template 'password_resets/new' 
    # Valid email 
    post password_resets_path, 
     params: { password_reset: { email: @user.email } } 
    assert_not_equal @user.reset_digest, @user.reload.reset_digest 
    assert_equal 1, ActionMailer::Base.deliveries.size 
    assert_not flash.empty? 
    assert_redirected_to root_url 
    # Password reset form 
    user = assigns(:user) 
    # Wrong email 
    get edit_password_reset_path(user.reset_token, email: "") 
    assert_redirected_to root_url 
    # Inactive user 
    user.toggle!(:activated) 
    get edit_password_reset_path(user.reset_token, email: user.email) 
    assert_redirected_to root_url 
    user.toggle!(:activated) 
    # Right email, wrong token 
    get edit_password_reset_path('wrong token', email: user.email) 
    assert_redirected_to root_url 
    # Right email, right token 
    get edit_password_reset_path(user.reset_token, email: user.email) 
    assert_template 'password_resets/edit' 
    assert_select "input[name=email][type=hidden][value=?]", user.email 
    # Invalid password & confirmation 
    patch password_reset_path(user.reset_token), 
      params: { email: user.email, 
        user: { password:    "foobaz", 
          password_confirmation: "barquux" } } 
    assert_select 'div#error_explanation' 
    # Empty password 
    patch password_reset_path(user.reset_token), 
      params: { email: user.email, 
        user: { password:    "", 
          password_confirmation: "" } } 
    assert_select 'div#error_explanation' 
    # Valid password & confirmation 
    patch password_reset_path(user.reset_token), 
      params: { email: user.email, 
        user: { password:    "foobaz", 
          password_confirmation: "foobaz" } } 
    assert is_logged_in? 
    assert_not flash.empty? 
    assert_redirected_to user 
    end 
end 

任意の助けいただければ幸いです。

+0

私はHartlのソースを調べました。この行は 'post password_resets_path、password_reset:{email:@ user.email}'です。あなたのパスワードは 'post password_resets_path、params:{password_reset:{email:@ user.email}}'彼のコードはエディション3だったことに注意してください。 – mrvncaragay

+0

これはうまくいきました!ありがとうございました! – Doughtz

+0

これを回答として提出できますか? – Doughtz

答えて

1

私はHARTLのソースに見て、彼はこのラインがあります。

post password_resets_path, password_reset: { email: @user.email }

をし、あなたがこのRails 5に互換性のある新しい構文である

post password_resets_path, params: { password_reset: { email: @user.email }} 

です。上記の解はRails 4です。

0

app/controllers/password_resets_controller.rbファイルに@user.update_attribute(:reset_digest, nil)がありません。以下のコンテンツでファイルを更新してください。

class PasswordResetsController < ApplicationController 
    before_action :get_user,   only: [:edit, :update] 
    before_action :valid_user,  only: [:edit, :update] 
    before_action :check_expiration, only: [:edit, :update] # Case (1) 

    def new 
    end 

    def create 
    @user = User.find_by(email: params[:password_reset][:email].downcase) 
    if @user 
     @user.create_reset_digest 
     @user.send_password_reset_email 
     flash[:info] = "Email sent with password reset instructions" 
     redirect_to root_url 
    else 
     flash.now[:danger] = "Email address not found" 
     render 'new' 
    end 
    end 

    def edit 
    end 

    def update 
    if params[:user][:password].empty?     # Case (3) 
     @user.errors.add(:password, "can't be empty") 
     render 'edit' 
    elsif @user.update_attributes(user_params)   # Case (4) 
     log_in @user 
     @user.update_attribute(:reset_digest, nil) 
     flash[:success] = "Password has been reset." 
     redirect_to @user 
    else 
     render 'edit'          # Case (2) 
    end 
    end 

    private 

    def user_params 
     params.require(:user).permit(:password, :password_confirmation) 
    end 

    # Before filters 

    def get_user 
     @user = User.find_by(email: params[:email]) 
    end 

    # Confirms a valid user. 
    def valid_user 
     unless (@user && @user.activated? && 
       @user.authenticated?(:reset, params[:id])) 
     redirect_to root_url 
     end 
    end 

    # Checks expiration of reset token. 
    def check_expiration 
     if @user.password_reset_expired? 
     flash[:danger] = "Password reset has expired." 
     redirect_to new_password_reset_url 
     end 
    end 
end 

更新は緑のテストを表示することができます。

関連する問題