Agile Web Development with Rails

Start from the beginning
                                        

tax = calc_sales_tax(amount)

EXEC SQL UPDATE orders set tax = :tax where id = :id;

}

EXEC SQL CLOSE c1;

EXEC SQL COMMIT WORK;

Scary stuff, eh? Don�ft worry. We won�ft be doing any of this, even though this style ofprogrammingis commonin scriptinglanguages such asPerl andPHP. It�fs also available in Ruby. For example, we could use Ruby�fs DBI library to produce similar-looking code. (This example, like the previous one, has no error checking.) Methodde.nition

page 632 ��.

def update_sales_tax

update = @db.prepare("update orders set tax=? where id=?")

@db.select_all("select id, amount from orders") do |id, amount|

tax = calc_sales_tax(amount)

update.execute(tax, id)

end

end

Report erratum

Prepared exclusively for Jordan A. Fowler

This approach is concise and straightforward and indeed is widely used. It seems like an ideal solution for small applications. However, there is a prob-lem.Intermixingbusinesslogic anddatabase accesslikethis can makeithard to maintain and extend the applications in the future. And you still need to knowSQLjust toget started onyour application.

Say, for example, our enlightened state government passes a new law that says wehave to record thedate and time that sales tax was calculated.That�fs not aproblem, we think.Wejusthave toget the current timein ourloop, add a column to theSQL update statement, andpass the time to the execute call.

But what happens if we set the sales tax column in many different places in the application? Now we�fll need to go through and .nd all these places, updating each.Wehaveduplicated code, and(if we miss aplace wherethe columnis set) wehave a source of errors.

In regularprogramming, object orientationhastaught usthat encapsulation solves these types of problems. We�fd wrap everything to do with orders in a class; we�fdhave a singleplace to update when the regulations change.

Folkshave extended theseideas todatabaseprogramming.Thebasicpremise is trivially simple. We wrap access to the database behind a layer of classes. The restof our application usesthese classes andtheir objects.it neverinter-acts with the database directly. This way we�fve encapsulated all the schema-speci.c stuff into a single layer and decoupled our application code from the low-leveldetails ofdatabase access.Inthe case of our salestax change, we�fd simply change the class that wrapped the orders table to update the time stamp whenever the sales tax was changed.

Inpractice this conceptisharder toimplement thanit might appear.Real-life databasetables areinterconnected(an order mighthave multiplelineitems, for example), andwe�fdliketo mirrorthisin our objects:the order object should contain a collection oflineitem objects.But wethen startgettingintoissues of object navigation,performance, anddataconsistency.Whenfaced with these complexities, the industry did what it always does: it invented a three-letter acronym:ORM, which standsfor object-relational mapping.Rails usesORM.

Object-Relational Mapping

ORMlibraries mapdatabase tables to classes.If adatabasehas a table called orders, our program will have a class named Order. Rows in this table corre-spond to objects of the class.aparticular orderis represented as an object of class Order.Withinthat object, attributes are usedtoget and settheindividual columns. Our Order object has methods to get and set the amount, the sales tax, and so on.

You've reached the end of published parts.

⏰ Last updated: Mar 22, 2008 ⏰

Add this story to your Library to get notified about new parts!

Agile Web Development with RailsWhere stories live. Discover now