Ruby on Rails:在没有goto的情况下处理重复错误检查的最佳方法?

时间:2011-05-27 21:07:28

标签: ruby-on-rails ruby goto

在有goto的语言中,我喜欢在函数末尾创建一个错误块(返回后),然后当我在函数中进行错误检查时,我可以简洁并转到每个检查中的错误处理程序。据我了解,这是goto的一个有效用途,不被认为是不好的做法。

伪代码示例:

 def example
   if (x) goto error
   do something
   if (y) goto error
   do something
   If (z) goto error
   do something
   return
  label 'error'
   log "error occurred"
   begin
     redirect_to :back
   rescue
     redirect_to root_url
   end
   return;
 end

正如您所看到的,在这种情况下,我的错误块与函数本身一样长,重复3次会使代码大小翻倍,而且不会很干。但是,看起来Ruby似乎并不支持goto,或者至少如果它支持goto,就像我在Google上看到的那样,它可能是一些可能被称为邪恶的笑话库。

因此,人们在Ruby中做什么来处理重复的错误检查,在每个错误中应该发生相同的结果?

2 个答案:

答案 0 :(得分:5)

回调

您应该使用Callbacks将其中许多错误转移到模型中。这些适用于与涉及数据库中的记录的操作相关的错误,即检查数据输入是否合适。

过滤器

使用before_filters和after_filters检查错误,尤其是当您需要对多个控制器操作执行这些检查时。一个例子:

before_filter :check_errors

def example
   regular code...
end

private
  def check_errors
    error checking...
  end

案例陈述

使用Case statements改进if语句,尤其是涉及多项检查时。

优先考虑上述

尽可能在模型中使用回调,并且无论何时都涉及数据保存/更新/验证。

每当代码要在多个操作中重复使用时,请使用before_filters(在我看来,无论何时您都参与此类错误检查)。

如果您需要这些检查仅发生一次,仅在此控制器操作中,不涉及更改记录,只需在有效的case语句中重写代码(但我的建议仍然是转移到before_filter)。

答案 1 :(得分:1)

这是一个小秘密:例外基本上是美化了。此外,ruby具有catch / throw语法,请参阅:http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html

在你的情况下,问一下,它确实是一个错误还是一个不受欢迎的情况。对我来说,一个错误是,belongs_to引用了一个不存在的记录,但没有一个空的belongs_to。这种情况因情况而异。

看看上面的评论,我想我会更倾向于添加一些设置实例变量并返回false的私有方法,并将它们链接在一起:

if load_model1 && load_model2 && load_model3
  ... do regular page view
else
  #render error page, use  @load_error
end

private
  def load_model1
     @model1 = ....
     if @model1.blank?  # or nil? or whatever error condition
        @load_error="model 1 failed
        return false
     else
        return true
     end
  end

  def load_model2
    ...
  end

  def load_model3
     ...
  end