"无法重定向到nil!"

时间:2016-04-14 10:47:31

标签: ruby-on-rails

我跟随迈克尔·哈特尔的导轨教程并做了一些小调整。用户可以在其配置文件上进行微博(状态更新),此时页面将显示为重新加载,并且将显示其新状态。我可以手工确认这完全符合预期。问题在于,由于某些原因,对它的测试没有通过,即使测试之外的最终结果看起来很完美。

microposts_controller.rb,microposts_interface_test.rb(失败测试),相关错误消息和users_controller.rb的屏幕截图,按顺序排列:http://imgur.com/a/IS1HI

microposts_controller.rb

class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Status updated!"
      redirect_to @user
    else
      @feed_items = []
      flash[:warning] = "Status was blank!"
      redirect_to @user
    end
  end

  def destroy
    @micropost.destroy
    flash[:success] = "Status deleted."
    redirect_to @user
  end

microposts_interface_test.rb

require 'test_helper'

class MicropostsInterfaceTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:mrtestit)
  end

  test "micropost interface" do
    log_in_as(@user)
    assert is_logged_in?
    # Invalid submission
    assert_no_difference 'Micropost.count' do
      post microposts_path, micropost: { content: "" }
    end
    # Valid submission
    content = "This status really ties the room together"
    assert_difference 'Micropost.count', 1 do
      post microposts_path, micropost: { content: content }
    end
    follow_redirect!
    assert_match content, response.body
    # Delete a post.
    assert_select 'a', text: 'delete'
    first_micropost = @user.microposts.paginate(page: 1).first
    assert_difference 'Micropost.count', -1 do
      delete micropost_path(first_micropost)
    end
    # Visit a different user.
    get user_path(users(:archer))
    assert_select 'a', text: 'delete', count: 0
  end

end

users_controller.rb

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
  before_action :correct_user, only: [:edit, :update]
  before_action :admin_user, only: :destroy

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

  def show
    @user = User.find(params[:id])
    if logged_in?
      @micropost = current_user.microposts.build
      @feed_items = current_user.feed.paginate(page: params[:page])
    end
    @microposts = @user.microposts.paginate(page: params[:page])
    redirect_to root_url and return unless @user.activated?
  end

我理解,出于某种原因,这是说@usernil。但是,我已多次确认redirect_to @user在其他任何地方都有效。

所有其他测试通过的事实已经证明了这一点,但为了更加努力,我已经确认失败的redirect_to @user代码行在其他文件中工作,例如当用户在其设置页面下更新其个人资料信息,然后重定向到他们的个人资料页面。我花了10多个小时在这上面工作(大部分是昨天),我正处于简单地删除这个测试并继续我的生活的边缘。 Stackoverflow是我最后的选择。

2 个答案:

答案 0 :(得分:4)

我认为你必须改变

redirect_to @user

redirect_to current_user

@user是类实例变量,必须手动创建,例如:

@user = User.find_by_id post.owner_id

虽然current_user是全局变量,但可以在任何地方使用。 但是不要忘记将其检查为零,因为用户无法登录!

您可以在每种方法中通过unless current_user.nil?手动检查它,或者更好地添加辅助方法并在控制器中使用它,教程已经用这种方式描述:

module SessionHelper
    def signed_in_user
        unless signed_in?
          store_location
          redirect_to signin_url, notice: "Please sign in."
        end
    end
# ...

class MicropostsController < ApplicationController
    before_action :signed_in_user
# ...

<强>更新 对于Aleks的建议:如果您想重定向发布可能不是当前用户的所有者,请使用

user = micropost.owner
redirect_to user

答案 1 :(得分:1)

有两种可能的解决方案。

首先是:

改变这个:

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Status updated!"
      redirect_to @user
    else
      @feed_items = []
      flash[:warning] = "Status was blank!"
      redirect_to @user
    end
  end

到此:

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Status updated!"
      redirect_to current_user
    else
      @feed_items = []
      flash[:warning] = "Status was blank!"
      redirect_to current_user
    end
  end

或(如果第一次没有工作)第二种方法:

更新此行:

before_action :correct_user,   only: :destroy

为:

before_action :correct_user,   only: [:create, :destroy]