Thursday, August 02, 2007

Torwards a Re-usable Object-Category Pattern?

I just built an application. The idea behind it is very simple. The implementation turned out to be surprisingly not so. Some of this reflects my own blind spots, which are legion, and some of it reflects some messiness inside WebObjects. It feels as though there should be a way to create an EO that captures some of what I am seeing here.

The application keeps track of a thing. In this case, I am keeping track of URLs, but it could be anything. The base EO has a primary key and a string for a name, and that is all. So, storing two of these, I would have (1001, 'http://www.google.com') and (1002, 'http://www.yahoo.com'), for instance. Then there is a many-to-many relationship between this and another object. This other object is a Category and looks like (2001, 'color', 'green'), (2002, 'priority', 'highest'), (2003, 'arfblat', 'Wednesday'). Then I implemented handleQueryForUnboundKey and handleTakeValueForUnboundKey in the URL object from the NSKeyValueCoding.ErrorHandling interface.

Essentially, what I am doing is taking this from the database:

URL: (1001, 'http://www.google.com')
URL: (1002, 'http://www.yahoo.com')
cat: (2001, 'color', 'green')
cat: (2002, 'priority', 'highest')
cat: (2003, 'arfblat', 'Wednesday')
join: (1001, 2001)
join: (1001, 2003)
join: (1002, 2002)
join: (1002, 2003)

and turning these into EOs which look like this:

{ pk: 1001, url: 'http://www.google.com', color: 'green', arfblat: 'Wednesday' }

{ pk: 1002, url: 'http://www.yahoo.com', priority: 'highest', arfblat: 'Wednesday' }

Simple? Well, probably not. But if you think about what Key Value Coding actually allows you to do, it makes sense.

If you use KVC to ask a URL object for an arfblat, it looks in the base EO and does not find anything. I implemented the handleQueryForUnboundKey method in the URL object to get the categories and see if any of them has a category name of 'arfblat'. If there is such a category, I get the category value, 'Wednesday', and return that.

So,

url.valueForKey("arfblat") -> "Wednesday"

Well, it was surprising to me how difficult it was to get this application to work right. It is still not quite working. I had to remove the ability to add new categories. If you create a new category and add objects to it, they look wrong, even though they are stored correctly in the database. Restart the app and all the objects behave correctly. There are a bunch of these kinds of quirks in dealing with this application.

I am going to have to think about this some more. If anyone has ideas or suggestions, please comment.