如何处理由nil引起的异常:NilClass

时间:2013-08-08 14:46:38

标签: ruby-on-rails-3 ruby-on-rails-4

我有一个名为quiz的模型,它有许多questions模型。我想添加一些esception处理,以便当用户在URL中键入错误的quiz_id时,将呈现错误页面。

我在QuestionsController中编写了一些辅助方法来处理异常:

private
def render_error(message)
    @error_message = message
    render 'error'
end

def active_quizzes_safe
    active_quizzes = Quiz.active_quizzes(current_user.id)
    render_error('Sorry! The request is invalid! Please log in again!') if active_quizzes.nil?
    active_quizzes
end


def active_quiz_safe(quiz_id)
    active_quiz = active_quizzes_safe.where(id: quiz_id).first
    render_error('The quiz does not exist or you are not allowed to take this quiz!') if active_quiz.blank?
    active_quiz
end

以下是QuestionsController中存在问题的操作:

def show_quiz
  if current_user
    @quiz = active_quiz_safe(params[:quiz_id])
    @questions = @quiz.questions
  end
end

因此,如果URL :quiz_id中的localhost:3000/MY_URL/:quiz_id不正确(即无法找到记录),则render_error方法应呈现错误页面。但是,当我厌倦了错误的:quiz_id时,我得到undefined method 'questions' for nil:NilClass。我想这是因为@questions = @quiz.questions方法中的show_quiz

然而,执行是否应该在render_error之前停止@questions = @quiz.questions行动?为什么@questions = @quiz.questions仍被执行?

另外,有没有任何标准方法来处理nil:像这样的NilClass错误?

谢谢!

2 个答案:

答案 0 :(得分:0)

调用render方法不会停止操作。因此,您应该仔细设计您的操作,以确保在渲染后立即返回。像这样:

def show_quiz
  if current_user
    active_quizzes = Quiz.active_quizzes(current_user.id)
    if active_quizzes.nil?
      render_error('Sorry! The request is invalid! Please log in again!')
    else
      @quiz = active_quizzes_safe.where(id: quiz_id).first
      if @quiz.blank?
        render_error('The quiz does not exist or you are not allowed to take this quiz!')
      else
        @questions = @quiz.questions
      end
    end
  end
end

但在这种情况下,我认为最好使用一些异常控制,如下所示:

def show_quiz
  if current_user
    active_quizzes = Quiz.active_quizzes(current_user.id)
    @quiz = active_quizzes_safe.find(quiz_id)
    @questions = @quiz.questions
  end
rescue ActiveRecord::RecordNotFound
  render_error 'The quiz does not exist or you are not allowed to take this quiz!'
end

答案 1 :(得分:0)

查看public/404.html, public/422.html and public/500.html个文件。如果发生错误,Rails将自动重定向。所以我认为除了具体的情况外,你不需要手动处理异常。要测试和查看此错误页面,请在生产bundle exec rails s RAILS_ENV=production中运行应用程序。