开发者

Ruby on Rails: Best way to handle repeated error checking without goto?

In languages that have goto, I like to create an error block at the end of a function (after return) and then when I do error checking within the function, I can just be concise and goto the error handler within each check. As I understand it,开发者_如何学编程 this is the one valid use of goto that isn't considered bad practice.

Example in pseudocode:

 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

As you can see, in this case, my error block is as long as the function itself, and repeating it 3 times would double the size of my code, and not be very DRY. However, it seems that Ruby doesn't support goto, or at least if it does, as best as I can tell from looking on Google, it's some sort of possibly joke library labeled evil.

Therefore, what are people doing in Ruby in order to handle repeated error checking where the same result should occur in each error?


Callbacks

You should transfer many of these errors into your models, using Callbacks. These apply to errors that are relevant to actions that involve records in your database, i.e. checking whether a data input is appropriate.

Filters

Use before_filters and after_filters to check for errors, especially when you need to perform these checks on multiple controller actions. An example:

before_filter :check_errors

def example
   regular code...
end

private
  def check_errors
    error checking...
  end

Case statements

Use Case statements to improve your if statements, particularly when you have multiple checks involved.

Prioritizing the above

Use callbacks in your models whenever you can and definitely whenever data saving/updating/validation is involved.

Use before_filters whenever the code is to be reused across multiple actions (and in my opinion, always whenever you have involved error checking like this).

If you need these checks to occur only once, in this controller action alone, that do not involve records being changed, simply rewrite your code in a valid case statement (but my recommendation would still be to transfer to a before_filter).


Here's a little secret: Exceptions are basically glorified gotos. Also, ruby has a catch/throw syntax, see: http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html

In your case, ask, is it really an error or just an undesirable condition. An error to me is when a belongs_to references a record that doesn't exist, but having an empty belongs_to isn't. This changes from situation to situation.

Looking at your comment above, I think I would be more inclined to add some private methods that set the instance variables and return true of false, and chain them together:

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜