繁体   English   中英

Ruby on Rails教程第12章创建了随机无关的错误

[英]Ruby on rails tutorial chapter 12 random unrelated errors created

这是我对应用程序开发的首次尝试,我几乎逐字遵循了Michael Hartl的教程。 一切顺利,直到第12章结束时,我的测试开始失败。 奇怪的是,失败的测试似乎与我在第12章所做的更改无关。

有三种故障和一种错误,并且在浏览器中手动检查时,本地服务器也会重复这些故障。 基本上,在执行动作之前,logged_in_user似乎不起作用,而仅适用于某些模型动作,而不是全部。 我尝试使用调试器对其进行跟踪,并尝试恢复到第12章之前的提交(所有这些都肯定有效),但是我在数据库迁移和填充方面遇到了麻烦,并且仅引入了越来越多的错误。 下面是错误日志,我的用户控制器,应用程序控制器和会话帮助器。 我觉得错误一定是其中之一。

在此先感谢您的帮助!

FAIL [“ test_should_redirect_update_when_not_logged_in”,UsersControllerTest,2016年3月6日05:58:45 -0800] test_should_redirect_update_when_not_logged_in#UsersControllerTest(1457272725.92s)预期为true或为零的test / controllers / users_controller_insert':insert'inblock'intest'

ERROR [“ test_should_redirect_destroy_when_not_logged_in”,UsersControllerTest,2016年3月6日05:58:45 -0800] test_should_redirect_destroy_when_not_logged_in#UsersControllerTest(1457272725.96s)NoMethodError:NoMethodError:未定义方法admin?' for nil:NilClass app/controllers/users_controller.rb:77:in admin?' for nil:NilClass app/controllers/users_controller.rb:77:in admin_user'test / controllers / users_controller_test.rb:47: block (2 levels) in <class:UsersControllerTest>' test/controllers/users_controller_test.rb:46:in 'app / controllers / admin_user' test/controllers/users_controller_test.rb:47:in :77:在admin_user' test/controllers/users_controller_test.rb:47:in block (2 levels) in <class:UsersControllerTest>' test/controllers/users_controller_test.rb:46:in块中在admin_user' test/controllers/users_controller_test.rb:47:in在'test / controllers / users_controller_test.rb:46:在'block in' admin_user' test/controllers/users_controller_test.rb:47:in块(2个级别)

FAIL [“ test_should_redirect_edit_when_not_logged_in”,UsersControllerTest,2016年3月6日05:58:46 -0800] test_should_redirect_edit_when_not_logged_in#UsersControllerTest(1457272726.03s)预期为true或为零的test / controllers / users_controller_intest'inblock。

FAIL [“ test_successful_edit_with_friendly_forwarding”,UsersEditTest,2016年3月6日05:58:46 -0800] test_successful_edit_with_friendly_forwarding#UsersEditTest(1457272726.07s)预期响应将重定向到<[已删除链接] / users / 633107804 / edit>重定向到<[已删除的链接] / users / 633107804>。 预期“ [[已删除的链接]] users / 633107804 / edit” ===“ [[已删除的链接]] users / users / 633107804”。 test / integration / users_edit_test.rb:22:in'中的阻止

class UsersController < ApplicationController

  before_action :correct_user, only: [:edit, :update]
  before_action :admin_user, only: :destroy
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User deleted"
    redirect_to_users_url
  end

  def show
    @user = User.find(params[:id])
    @microposts = @user.microposts.paginate(page: params[:page])
  end

  def new
    @user = User.new
  end

  def index
    @users = User.paginate(page: params[:page])
  end

  def create
    @user = User.new(user_params)
   if @user.save
     @user.send_activation_email
     flash[:info] = "Please check your email to activate your account."
     redirect_to root_url
   else
     render 'new'
   end
  end

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

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  def following
    @title = "Following"
    @user = User.find(params[:id])
    @users = @user.following.paginate(page: params[:page])
    render 'show_follow'
  end

  def followers
    @title = "Followers"
    @user = User.find(params[:id])
    @users = @user.followers.paginate(page: params[:page])
    render 'show_follow'
  end

  private

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

    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end

    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end


end

和应用程序控制器:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

include SessionsHelper

private

#confirms a logged in user. Now placed in the application controller so both teh user controller and microposts controller can use it
def logged_in_user
  unless logged_in?
    store_location
    flash[:danger] = "Please log in."
    redirect_to login_url
  end
end

end

和会话助手:

module SessionsHelper
  #logs in the given user
  def log_in(user)
    session[:user_id] = user.id
  end

  # returns the current logged-in user (if any)
  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: session[:user_id])
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

  # returns true if the user is logged in, and false otherwise
  def logged_in?
    !current_user.nil?
  end

  #Saves a user id and remember token digest to cookies 
  def remember(user)
    user.remember
    #Code to save cookies with 20 year expiry ("permanent") and "signed" so it can't be accessed by third party
    cookies.permanent.signed[:user_id] = user.id
    cookies.permanent[:remember_token] = user.remember_token
  end

  # runs the forget method and removes remember tokens from cookies
  def forget(user)
    user.forget
    cookies.delete(:user_id)
    cookies.delete(:remember_token)
  end

  # logs out the given user
  def log_out
    forget(current_user)
    session.delete(:user_id)
    @current_user = nil
  end

  def current_user?(user)
    user == current_user
  end

  # Redirects to stored location after trying to edit while logged out and then logging in
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end

  # Stores the URL trying to be accessed
  def store_location
    session[:forwarding_url] = request.url if request.get?
  end

end

用户控制器测试:

require 'test_helper'

class UsersControllerTest < ActionController::TestCase
  def setup
    @user = users(:Joe)
    @other_user = users(:Jane)
  end

  test "should redirect to index when not logged in" do
    get :index
    assert_redirected_to login_url
  end

  test "should get new" do
    get :new
    assert_response :success
  end

  test "should redirect edit when not logged in" do
    get :edit, id: @user
    assert_not flash.empty?
    assert_redirected_to login_url
  end

  test "should redirect update when not logged in" do
    patch :update, id: @user, user: { name: @user.name, email: @user.email }
    assert_not flash.empty?
    assert_redirected_to login_url
  end

  test "should redirect edit when logged in as wrong user" do
    log_in_as(@other_user)
    get :edit, id: @user
    assert flash.empty?
    assert_redirected_to root_url
  end

  test "should redirect update when logged in as the wrong user" do
    log_in_as(@other_user)
    patch :update, id: @user, user: { name: @user.name, email: @user.email }
    assert flash.empty?
    assert_redirected_to root_url
  end

  test "should redirect destroy when not logged in" do
    assert_no_difference 'User.count' do
      delete :destroy, id: @user
      end
        assert_redirected_to login_url
  end

  test "should redirect destroy when logged in as a non-admin" do
    log_in_as(@other_user)
    assert_no_difference 'User.count' do
      delete :destroy, id: @user
    end
    assert_redirected_to root_url
  end
end

在将您的代码与教程代码中的代码进行比较之后,请尝试更改UsersController before_action语句的顺序,看看是否before_action

之前:

  before_action :correct_user, only: [:edit, :update]
  before_action :admin_user, only: :destroy
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]

后:

  before_action :logged_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]
  before_action :correct_user, only: [:edit, :update]
  before_action :admin_user, only: :destroy

所有before_action语句均按照在控制器中定义的顺序运行,因此对于update操作,您当前正在首先运行correct_user过滤器,该过滤器调用current_user?(@user) ,该过滤器调用current_user

  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: session[:user_id])
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

那时在测试中,由于尚未登录用户,因此没有session[:user_id] ,因此if语句失败,并且也没有cookies.signed[:user_id] ,所以elsif语句失败,给您返回nil返回值, @current_user未设置@current_user

在测试中的请求的某个时刻,您似乎正在找到将其转移到admin_user方法的方法,该方法正在调用current_user.admin? ,由于此时current_usernil ,因此您将获得NoMethodError: undefined method admin?' for nil:NilClass NoMethodError: undefined method admin?' for nil:NilClass您看到的NoMethodError: undefined method admin?' for nil:NilClass

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM