Michael Hartl 的 Rails 教程第 9 章(第 9.12 节)测试失败 "undefined local variable or method"

Michael Hartl’s Rails Tutorial chapter 9 (section 9.12) tests failed "undefined local variable or method"

我正在阅读 Michael Hartl 的 Rails 教程,但在实施高级登录时我陷入了测试(第 9.12 节)。

到目前为止我已经通过了所有测试,但是在使用有效信息测试登录时出现错误。似乎有些东西没有明确定义或缺失。 有什么帮助吗?谢谢

Test output

UserLoginTest

    require 'test_helper'

class UsersLoginTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "login with invalid information" do
    get login_path
    assert_template 'sessions/new'
    post login_path, params: {session: {email:"", password:""}}
    assert_template 'sessions/new'
    assert_not flash.empty?
    get root_path
    assert flash.empty?
  end

  test "login with valid information" do
    get login_path
    post login_path, params: { session: { email: @user.email, password: 'password' } }
    assert_redirected_to @user
    follow_redirect!
    assert_template 'users/show'
    assert_select "a[href=?]", login_path, count: 0
    assert_select "a[href=?]", logout_path
    assert_select "a[href=?]", user_path(@user)
  end

  test "login with valid information followed by logout" do
    get login_path
    post login_path, params: { session: { email: @user.email, password: 'password' } }
    assert is_logged_in?
    assert_redirected_to @user
    follow_redirect!
    assert_template 'users/show'
    assert_select "a[href=?]", login_path, count: 0
    assert_select "a[href=?]", logout_path
    assert_select "a[href=?]", user_path(@user)
    delete logout_path
    assert_not is_logged_in?
    assert_redirected_to root_url
    follow_redirect!
    assert_select "a[href=?]", login_path
    assert_select "a[href=?]", logout_path,      count: 0
    assert_select "a[href=?]", user_path(@user), count: 0
  end

end

SessionsHelper

module SessionsHelper
def log_in(user)
  session[:user_id] = user.id
end
def current_user
  if (user_id = session[:user_id])
    @current_user ||= User.find_by(id: user_id)
  elsif (user_id = cookies.signed[:user_id])
  user = User.find_by(id: user_id)
  if user && user.authenticated?(cookies[:remember_token])
    log_in user
    @current_user = user
  end
  end   
end
def remember(user)
  user.remember
  cookies.permanent.signed[user_id] = user.id
  cookies.permanent[:remember_token] = user.remember_token
end
def logged_in?
  !current_user.nil?
end
def forget
  user.forget
  cookies.delete(:user_id)
  cookies.delete(:remember_token)   
end
def log_out
  forget(current_user)
  session.delete(:user_id)
  @current_user = nil
end

结束 会话控制器

    class SessionsController < ApplicationController
  def new
  end

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

  def destroy
    log_out
    redirect_to root_url
  end

end

您的测试输出表明在 sessions_helper.rb 的第 18 行有一个未定义的局部变量 user_id。如果我们查看代码中的那一行,我们会看到这个方法:

def remember(user)
  user.remember
  cookies.permanent.signed[user_id] = user.id
  cookies.permanent[:remember_token] = user.remember_token
end

错误发生在您尝试执行 cookies.permanent.signed[user_id] 的地方。您可能忘记了一个冒号并打算说 cookies.permanent.signed[:user_id]。没有冒号,ruby 认为 user_id 是一个局部变量而不是一个符号,并且会抛出您看到的错误。