Stored Procedures and Rails - Part 2

4 12 2007


Continued from Stored Procedures and Rails - Part 1

Now we know how to call our good and reliable stored procedures but there is a difference when we get records from database using Rails ORM/ActiveRecord compared to a stored procedure. This requires a different approach to access records returned from a stored procedure.

Lets say we have a table orders and a corresponding model Order. We all know, how to access data using ActiveRecord, eg.

@orders = Order.find(:all, :conditions => ["some simple condition"])

then what is returned to us is an array of order objects which we can access by either using a block or a for loop. For instance,

for order in @orders
  puts order.order_name
end

but this is not possible in case if we use a stored procedure to get data on orders because we don’t get back an array of order objects instead we simply get back an array of hashes, ie. an array of records with their attributes and values. Hence, the above code will not work.
Lets say you call your stored procedure, like this

@orders = CallStoredProcedure.fetch_records("exec procedure_name 'args1', 'args2'")

as mentioned in the previous post.
Then you need to access records with a little modification within your for loop

for order in @orders
  puts order['order_name']
end

I thought this might save sometime who are new to using stored procedures.

NOTE: The only downside of using stored procedures in Rails currently is; you cannot use the Object Relational Mapping which you might have been used to by know, ie. picking all children of an order by simply typing

order.children

The best thing to do is to use stored procedures judiciously and mainly for complex logic/calculation in your database but when you want to do something simple with your data like simply showing something or a quick update then use ORM over stored procedures.


Sign up and be a part of SPhred.com and don’t forget to invite your friends ;o)






Stored Procedures and Rails - Part 1

3 12 2007


There is no documentation in Rails about how to use stored procedures or atleast it is difficult to find where to look at. And according to DHH stored procedures is not the Rails Way to do things. DHH mentioned in his post

I want a single layer of cleverness: My domain model. Object-orientation is all about encapsulating clever. Letting it sieve half ways through to the database is a terrible violation of those fine intentions. And I want no part of it.

I somewhat agree to what DHH has to say. And that’s all fine but what if we don’t have any other option apart from using stored procedure and our stored procedure has some complex logic which we don’t want to put in our Ruby code then here is a little hack to it

ActiveRecord::Base.connection.execute("execute procedure_name")

But the above line will not return anything it will only execute your procedure, considering everything went OK.

Moreover, it’s not DRY if everytime you have to write that line of code just to call a procedure.

Here is a better way to do it:

1) Create a class and let’s call it

Class CallStoredProcedures
  your methods here .......
end

2) Create a class method within it

def self.fetch_db_records(proc_name_with_parameters)
  ActiveRecord::Base.connection.execute(proc_name_with_parameters)
end

Then simply call it as

CallStoredProcedures.fetch_db_records("exec procedure_name 'args1', 'args2', 'and so on' ")

Now you might say, that this will only execute a procedure (as I mentioned above) what if I want to return records or values from stored procedures. Then I will prefer class methods and this is how I would do it,

class CallStoredProcedures < ActiveRecord::Base

  def self.fetch_db_records(proc_name_with_parameters)
    connection.select_all(proc_name_with_parameters)
  end

  def self.insert_update_delete_calculate(proc_name_with_parameters)
    connection.execute(proc_name_with_parameters)
  end

  def self.fetch_val_from_sp(proc_name_with_parameters)
    connection.select_value(proc_name_with_parameters)
  end

end

And then simply call it like

CallStoredProcedures.method_name("exec procedure_name 'args1', 'args2', 'and so on' ")

Sweet…

If you know a better way to do it then I would love to know your views.

Stored Procedures and Rails - Part 2


Sign up and be a part of SPhred.com and don’t forget to invite your friends ;o)