退出失败验证的更优雅方式

时间:2014-05-01 23:19:36

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

我的Question模型有很多Answer

我正在验证为每个问题创建的答案不超过三个:

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

代码正在运行,当答案太多时我得到“回滚事务”和“RuntimeError:无法创建答案。”

但是,对于collection_association.rb中的不同行,有20行路径引用。这是你做错事时的典型表现。

这是应该的,还是我的验证有点过于残酷?

1 个答案:

答案 0 :(得分:2)

要抑制因error stacktrace回调引起的丑陋before_add和错误,您可以做的是rescue引发的错误。

例如:

更新您的question.rb,如下所示:

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

在此更新create

中的QuestionsController操作后
def create
  ## ...
  begin
    if @question.save
      ## ...
    else
      ## ..
    end 
  rescue AnswersLimitExceeded
    render action: 'new' 
  end
end

这种方式,只要在创建AnswersLimitExceededQuestion模型中出现associated answers,就会在控制器级中获救,从而抑制特定错误{{ 1}}优雅地留言AnswersLimitExceeded

另外,如果你注意到我创建了一个单独的错误类,即Too many answers,那么我在Controller中拯救AnswersLimitExceeded这个特殊的异常,而不是所有其他异常。