Thursday, January 26, 2006

One to One relationship - Agile Web Development with Rails

I am a bit confused with some of the Database table relationships as discussed in the Agile Web Development book.

For One-To-One association, the book used the Invoice and Order example (Pg 220). In this case, an order may be associated with one or zero invoices while an invoice always refers to an order.

As per Rails convention, since invoice belongs_to the order, it will have an order_id as a foreign key in its DDL. And the order table needs no change.

However I feel this convention creates inefficient database relationships. Since an order can be associated with one or zero invoices, to find if an order has an invoice associated with it, I would need to look through the entire invoices table to find a row
that has that particular order_id. If an order has no invoice associated with it, I would end up going through the entire invoices table to determine that. If on the other hand, I keep the invoice id as a FK in the order table, it is much more efficient to determine whether an order has an invoice associated with it. Granted the Foreign key can be indexed and optimized, but the fact remains that it is not required to begin with. If an order table contains an invoice_id that is not null, we know an invoice exists, else a corresponding invoice doesn't exist for the order.
Then to find the associated order of an invoice, we could worst case go through the entire orders table. However since we know an invoice can never exist without an order, it will never be as inefficient. We could also put an order_id in the invoices table to save this search of the orders table, but then would Rails be able to deal with
relationships where two tables both "belongs_to" each other?

Also in the code for this example, the book said that the has_one and belongs_to differ in the way they save (or don't save) objects to the database. If I assign an object to a belongs_to association, it will never be automatically saved.
However later while discussing the belongs_to association, (pg 223), the book describes code for creation of a line item and the associated new product. The Line Item model belongs_to the Product model. Here the book says that the product gets saved automatically and links the line item to that new product's id. This seems contradictory. Am I mistaken in understanding the concept?

I guess I am not clear on how the belongs_to and has_one relationships work.
For e.g. suppose I had a user and an account table. Both of these table contain a common text field called note. If I want to create a separate Notes database table for the note field, I would extract the note field out of the user and the account tables. I should then ideally end up with a note_id in both the user and the account table which refers to a row in the Notes table. Then when I fetch a user (or an account), I can fetch the note from the notes table since I know the corresponding note_id.
If I were to follow the Rails convention, a User (and an account object) "has_one" note. And a note "belongs_to" a user (or an account object).
But that means in the DDL, only the notes table will be changed to contain two foreign keys to refer to the user and account obj resp. Now a) this means there will always be one redundant field in each note row in the database and b) to find a note corresponding to a user row, I may have to search through the entire notes table in the worst case.
I could move the belongs_to association to the user (or the account) table. The user model would then have a belongs_to :note declaration and subsequently the user table will have a note_id in it.
Would that be the correct association then? Are there any pitfalls with this such as while creation and saving of the object when assigned to the belong_to association?

0 Comments:

Post a Comment

<< Home