Wednesday, March 12, 2008

Begin Rescue Else End

So today I was working on a project. This project will be an admin interface for an application that has already been running for a while(which was written in PHP). So I am having to use a legacy database(tutorial coming soon for making admin interface for a legacy DB!) Anyway, I have an employee, and a department. The employee references which department he is in by the ID. However, some employees have an ID that is not used in the department table(department got deleted at some point, never existed, who knows?).


In my employee model, I am making a function to take the department id from the employee tables(thisdept), and look up the number in the department table to get the name of the department, all pretty standard stuff.

Here is what I tried first:



def deptname
dept = Department.find(thisdept)
dept.name
end



ActiveRecord::RecordNotFound in Employees#index

Showing vendor/plugins/active_scaffold/frontends/default/views/_list_record.rhtml where line #10 raised:

Couldn't find Department with ID=13


So we are going to need something along the lines of a try - catch. Ruby's equivalent is the begin-rescue-else-end. Begin is the code that might throw an error. Rescue is the code to excute if there is an error. Else is executed if there is no error. You can also add an ensure block, which will be run after everything, regardless. Here is my fix:




def deptname
begin
dept = Department.find(thisdept)
rescue
"No Department"
else
dept.name
end
end

Works like a charm! See you next time.

8 comments:

Derek Berner said...

Hey man --

How about this?

def deptname
Department.find(thisdept).name rescue "No Department"
end

Inline rescues are my friend ;-)

rledge21 said...

Awesome, didn't know about inline rescues, thanks for the tip.

Anonymous said...

thats more like it

meceo said...

I don't like rescue in this example, that will catch all exceptions, no matters what went wrong

dep = Department.find_by_id(thisdept)
dep.present? ? dep.name : "No Department"

no rescue required

Soro said...

rescue ROX! And the inline use is more 'polite' I must say.

@meceo argument is silly "I don't like rescue in this example, that will catch all exceptions, no matters what went wrong"
Isn't that the whole point?!

What if someone just destroyed the dept. he was looking for?

Anonymous said...

@Soro
The point is that dependent on the error you might want to do more than only print "No Department" to the user.
Maybe you additionally want to fire a systems management event if (and only if) you have a db error.

Greetings
Heinz

Anonymous said...

Thank you! Helped me get some safety into my application. I am catching all those bad people trying to grab orders they shouldn't be seeing.

Have a nice life!

Michael

Generic Viagra said...

I was looking for this information, thanks for put in this easy way, I mean in a easy way to understand it jajaja, well until the next time.