This is a reposting of an email I sent Frank Lee, who I’ve tapped to help out in building optimized queries for ThyncRecord. Just figured I’d share.
To generate the SQL for a query, it is necessary to examine a particular model’s associations and the associated models’ associations, recursively until we reach the appropriately-defined depth. It is of course also necessary to know the data type for each column of the currently-being-built object, It is most important to know upon save, preventing improper types being stored in the db, formatting the query strings appropriately with quotes or without, outputting error messaging, etc. Likewise validation rules may output similar error messaging, as defined by the user of the library via regex. (may implement add’l validation in the future)
Associations which can be defined should include at a minimum: belongs_to and has_one, which are essentially the same thing but seen from different perspectives; has_many, which maps an array of the associated model’s Records to a plural property name on the root Record object; and has_and_belongs_to_many, which will map an array of associated Records from either end. Determining where to cutoff preloading of these properties is a significant decision to make still. Preventing circular references, etc may be important.
An example of ThyncRecord usage would be storing various users’ payment info. We might define a User model and a PaymentMethod model, where the User has_many PaymentMethods, and a PaymentMethod belongs_to a User. All of this is accomplished declaratively (along with defining all columns and add’l validation). Schema is created by means of migrations or model declarations alone. (I may also implement the Rails concept of fixtures which will load data directly into the db from formatted text, in this case JSON) A call to return the second payment type for user 3 might be:
var payment_meth = User.find(3).payment_methods;
Let’s also presume that this new object is assigned an ID of 543, (it’s record 543 in the payment_methods table) though the user needs not know of this. You might then update the billing address (a text field) of this payment method (we can assume it’s a credit card, perhaps):
payment_meth.billing_address = "123 Some Place, Sometown, ZZ 90876"; payment_meth.save();
Calling save will first verify that some data has changed from the initially-loaded state, and if it has it will pass over into the validation process for any sub-objects first, then on to the current Record. In this case we have no sub-objects, only a text field to worry about. It should write out something like
"UPDATE payment_methods SET billing_address='123 Some Place, Sometown, ZZ 90876' WHERE id=543";
The Record object passes back the updated data to its corresponding Model (all Records contain a key to the master models hash stored in ThyncRecord for the purposes of navigating through associations).”
Anybody w/ questions or who feels like contributing, feel free to email me (firstname.lastname@example.org).
[EDIT: ThyncRecord is now JazzRecord and will be available for download from www.jazzrecord.org starting 10/21/08]