Friday, September 21, 2007

Ruby, ActiveRecord and Database Functions

Here's a neat little trick you might not know.  Rails (well, ActiveRecord) tends to do all of your SQL for you, right?  So you don't have to write a bunch of selects and joins to get at your data.  Fair enough.  Well, what happens when you need to do a manipulation on that data?  I have a case right now where I need to get the date_of_birth field of out my model.  The only problem is that it is stored encrypted, and I need to call my companies internal decrypt() method on it. 

The find method actually has what you need already built in, by passing a :select param into it.  Normally you'd be selecting *, but what you want to do here is change it for your specific purpose.  So in my Document class I have this:

 

def dob

  Document.find(id, :select=>'decrypt(date_of_birth) as dob').dob

end

 

Done!  Now once I have  Document object, the dob property appears just like any other. 

I realize that this trick only goes half way in that it makes a find() call whenever you access the parameter.  In reality I should figure out a way to make this trick integrate directly with the main instantiation of the object so there's not a second call involved.  But for this project I'm working with a small number of documents, and the extra database hit won't hurt me.  Anybody else want to chime in with a better way to integrate it?

 

Technorati tags: , , ,

1 comment:

Teste said...

I am facing the same problem but to create a record

hash = {:data_now => 'now()',:value => 1}
Pos.create(hash)

the sql that activerecord generates is

insert into pos(data_now,value)
VALUES('now()',1)
he puts the funcion now as a string.
how to avoid that?