2015-08-26 5 views
1

Я видел эту конкретную ошибку (или вопрос/тему) во многих других местах. Однако ни одно из решений не решило мою проблему. Что касается главы 8 Michael Hartl книги, я добавил следующий тест интеграции:NoMethodError: undefined method `remember_token 'для nil: NilClass

test "login with remembering" do 
    log_in_as(@user, remember_me: '1') 
    assert_not_nil cookies['remember_token'] 
    assert_equal cookies['remember_token'], assigns(:user).remember_token 
end 

Однако последний assert_equal дает мне ошибку, я положу в названии.

То, что я сделал до сих пор:

Предложил другие вопросы, я породили другую миграцию, добавив remember_token к User модели. Однако это не решило проблему.

Как я могу это решить?

+0

Являются ли @user и присваивают (: пользователь) те же экземпляры в вашем тесте? Попробуйте '@ user.remember_token' вместо 'assigns (: user) .remember_token' – chumakoff

ответ

1

Проблема есть, вероятно, не то, что User модель не имеет remember_token атрибут, а о том, что значение assigns(:user) равно нулю, что означает, что ваш контроллер не правильно установлен атрибут @user.

+0

Спасибо Simone. Прямо сейчас у меня есть '@user = User.new (user_params)', а 'user_params' определяется как' def user_params params.require (: user) .permit (: name,: email,: password, : password_confirmation) конец'. Это проблема? –

+0

Я предполагаю, что это ваше новое действие, тогда как логин, вероятно, происходит в действии create. –

+0

Это мое создать действие: определение функции создания \t @user = User.new (user_params) \t если @ user.save log_in @user \t \t вспышки [: успех] "! Добро пожаловать" = \t \t redirect_to @user \t еще \t \t делают 'новый' \t конец end' Видите ли вы какие-либо проблемы в нем? –

0

В вашем тесте присваивание (: пользовательский) экземпляра не существует. Вы используете экземпляр @user в методе log_in_as. Почему вы не используете его в своем последнем методе assert_equal? Попробуйте это

assert_equal cookies['remember_token'], @user.remember_token 

Я думаю, это сработает.

И узнайте, почему вы используете назначает (: пользователь) и почему он равен нулю.

Отредактировано:

Если он не будет работать, то сначала попробуйте перезагрузить пользовательские данные, прежде чем сделать утверждение:

@user.reload 
assert_equal cookies['remember_token'], @user.remember_token 

И я хотел бы добавить еще одно утверждение к тесту, который проверяет если пользователь имеет «remember_token» после входа в систему. Это поможет вам обнаружить неправильное место в вашем коде. Если это утверждение не удастся, вы убедитесь, что что-то не так в вашем процессе авторизации.

test "login with remembering" do 
    log_in_as(@user, remember_me: '1') 
    @user.reload 
    assert_not_nil @user.remember_token 
    assert_not_nil cookies['remember_token'] 
    assert_equal cookies['remember_token'], @user.remember_token 
end 
+0

Я попробовал, но это не решило проблему. –

+0

Я отредактировал ответ – chumakoff

1

Не видя полное сообщение об ошибке, это трудно точно знать, где проблема, но когда я побежал в этом это было потому, что я забыл, чтобы спасти мой sessions_controller.rb перед запуском теста.

Вот точная ошибка я получил:

ERROR["test_login_with_remembering", UsersLoginTest, 2016-03-03 20:00:56 -0600] 
test_login_with_remembering#UsersLoginTest (1457056856.16s) 
NoMethodError:   NoMethodError: undefined method `remember_token' for nil:NilClass 
     test/integration/users_login_test.rb:42:in `block in <class:UsersLoginTest>' 
    test/integration/users_login_test.rb:42:in `block in <class:UsersLoginTest>' 

Ниже мой метод создания внутри контроллера сессий:

def create 
    @user = User.find_by(email: params[:session][:email].downcase) 
    if @user && @user.authenticate(params[:session][:password]) 
    log_in @user 
    params[:session][:remember_me] == '1' ? remember(@user) : forget(@user) 
    redirect_to @user 
    else 
    flash.now[:danger] = 'Invalid email/password combination' 
    render 'new' 
    end 
end 
1

Проверьте sessions_controller. Он должен использовать переменную экземпляра (@user) внутри метода create, где бы вы ни ссылались на пользователя.

def create 
    @user = User.find_by(email: params[:session][:email].downcase) 
    . 
    . 
    . 
end 

Rails Tutorial - Глава 9.26 Упражнения 1)

Inside a test, you can access instance variables defined in the controller by using assigns with the corresponding symbol. For example, if the create action defines an @user variable, we can access it in the test using assigns(:user).

Изменения метода создания использовать переменный экземпляр было оставлено в качестве упражнения возле главы 9.26. Но метод users_login_test «login with remembering» полагается на assigns (: user) для доступа к remember_token.

test "login with remembering" do 
    log_in_as(@user, remember_me: '1') 
    assert_equal assigns(:user).remember_token, cookies['remember_token'] 
    assert_not_empty cookies['remember_token'] 
    end 
Смежные вопросы