ruby-on-rails - 一种更优雅的退出验证失败的方法

标签 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 行路径引用到不同的行。这是您做错事时的典型表情。

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

最佳答案

要抑制由于 before_add 回调引起的难看的 error stacktrace 和错误,您可以做的是 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

在此更新 QuestionsController 中的 create 操作之后

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

这样,只要在创建相关答案时在Question 模型中引发AnswersLimitExceeded,就会在 Controller 级别 从而优雅地抑制特定错误 AnswersLimitExceeded 和消息 Too many answers

此外,如果您注意到我创建了一个单独的错误类,即 AnswersLimitExceeded,那么我在 Controller 而不是所有其他异常中挽救这个特定异常。

关于ruby-on-rails - 一种更优雅的退出验证失败的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23418321/

相关文章:

ruby-on-rails - 如何在不更改原始类的情况下替换 belongs_to 关联

ruby-on-rails - 纬度和经度的数据类型正确吗? (在事件记录中)

ruby-on-rails - 我应该如何将自定义属性添加到 Rails 辅助方法?

ruby-on-rails - 根据父属性验证子项

ruby-on-rails-4 - Michael Hartl RoR 教程第 12 章练习 #2

ruby-on-rails - 如何阻止登录用户删除自己的帐户

ruby-on-rails - 检查 activerecord 是否锁定在 "updating"状态

ruby-on-rails - 如何使用 capybara 测试图像的src和alt值?

ruby-on-rails - 如何使用 Redcarpet for Rails 在 Markdown 中嵌入 YouTube 视频?

sql - 从 rails 5 获取随机记录,但在顶部保留一条记录(基于某个值)