【问题标题】:cannot instantiate service object无法实例化服务对象
【发布时间】:2013-12-04 18:30:20
【问题描述】:

我正在尝试对我的 Rails 应用程序进行一些重构。

我创建了一个 QuizCompletion 服务对象 (app/services/quiz_completion.rb):

class QuizCompletion
  def initialize(quiz, user)
    @quiz = quiz
    @user = user
  end

  def pass?
    wrong_answers = 0
    @quiz.questions.each do |question|
      answer = @user.answers.where("question_id = ?", question.id).first
      if !answer.correct
        wrong_answers += 1
      end
    end
    if wrong_answers > 2
      return false
    else
      return true
    end
  end
end

然后在我的 QuestionsController 中尝试实例化服务对象:

class QuestionsController < ApplicationController
  before_filter :require_user
  def show
    @quiz = Quiz.find(params[:quiz_id])
    @question = Question.next(params[:id])
    if @question != nil
      redirect_to quiz_path(@quiz.id, question_id: @question.id)
    else
      evaluation = QuizCompletion.new(@quiz, current_user)  #instantiate Service Object!
      if evaluation.pass? 
        Quiz.complete(current_user, @quiz)
        redirect_to quiz_complete_path(@quiz.id)
      else
        redirect_to quiz_fail_path(@quiz.id)
      end
    end
  end

私人的 结束

但是,当我运行控制器测试时,我收到了这个错误:

Failure/Error: get :show, quiz_id: @quiz.id, id: question3.id
 NoMethodError:
   undefined method `stringify_keys' for #<Quiz:0x007fd781515300>

有人知道发生了什么吗?为什么我不能在 QuestionsController 中实例化 QuizCompletion 对象?

感谢您的帮助,

安东尼

【问题讨论】:

  • 错误出现在哪一行?
  • 你也可以发布你的测试和控制器的代码吗? @quiz 来自哪里?
  • @TheDude,错误发生在我实例化服务对象的那一行:evaluation = QuizCompletion.new(@quiz, current_user)
  • @Blue Smith,我添加了 QuestionsController 的代码,并在我实例化服务对象的地方添加了注释。 quiz 是在 questions#show 操作方法中设置的实例变量。

标签: ruby ruby-on-rails-4


【解决方案1】:

发现了问题,显然问题出在我的服务对象的命名上。 Rails 框架对 quiz_completion.rb 名称感到困惑,因为已经存在 Quiz (quiz.rb) 模型。

所以我把我的服务对象的名字改成了Evaluation (evaluation.rb):

class Evaluation
  def initialize(quiz, user)
    @quiz = quiz
    @user = user
  end

  def pass?
    wrong_answers = 0
    @quiz.questions.each do |question|
      answer = @user.answers.where("question_id = ?", question.id).first
      if !answer.correct
        wrong_answers += 1
      end
    end
    if wrong_answers > 2
      return false
    else
      return true
    end
  end
end

当我从 QuestionsController 中调用它时,这个名称也更有意义:

evaluation = Evaluation.new(@quiz, current_user)
  if evaluation.pass? 
    Quiz.complete(current_user, @quiz)
    redirect_to quiz_complete_path(@quiz.id)
  else
    redirect_to quiz_fail_path(@quiz.id)
  end

【讨论】:

    【解决方案2】:

    我也无法实例化我的第一个服务对象 - 我收到此错误

    uninitialized constant MyServiceObject (NameError)
    

    我正在使用 spring 并且不得不停止它:spring stop。之后就成功了。

    【讨论】:

      猜你喜欢
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 2016-01-18
      • 2018-10-04
      • 2011-06-28
      • 2012-08-04
      • 1970-01-01
      相关资源
      最近更新 更多