문제

I have a Question model that has many Answer.

I'm validating that not more than three answers are created for each question:

has_many :answers, -> { order(position: :asc) }, before_add: :set_nested

private    
def set_nested(answer)
  if answers.size > 3
    errors.add(:base, "Too many answers.")
    raise "Unable to create answer."
  else
    answer.question ||= self
  end
end

The code is working, when there are too many answers I get "rollback transaction" and "RuntimeError: Unable to create answer."

But then threre are 20 lines of path references to different lines in collection_association.rb. It's the typical look when you have done something wrong.

Is this as it should be or am I doing the validation a bit too brutal?

도움이 되었습니까?

해결책

To suppress the ugly error stacktrace and error raised due to before_add callback, what you can do is rescue the raised error.

For example:

Update your question.rb as below:

class AnswersLimitExceeded < StandardError; end ## Add this

class Question < ActiveRecord::Base
has_many :answers, -> { order(position: :asc) }, before_add: :set_nested

private    
def set_nested(answer)
  if answers.size > 3
    errors.add(:base, "Too many answers.")
    raise AnswersLimitExceeded, "Unable to create answer." ## Change here
  else
    answer.question ||= self
  end
end

After this update the create action in your QuestionsController

def create
  ## ...
  begin
    if @question.save
      ## ...
    else
      ## ..
    end 
  rescue AnswersLimitExceeded
    render action: 'new' 
  end
end

This way whenever AnswersLimitExceeded is raised within your Question model while creating the associated answers then it is rescued at controller level thereby suppressing the specific error AnswersLimitExceeded with message Too many answers elegantly.

Also, if you notice I created a separate Error class i.e., AnswersLimitExceeded so that I rescue ONLY this particular exception in Controller and not all others.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top