Tue, 18 May 10

AirDB can has_many_through

We now have a better, declarative and richer mechanism of specifying model relationships. In the process, AirDB now has support for has_many_through associations.

As discussed earlier for join table attributes, the cleanest way to express the association is a has_many_through, where two models have a many to many relationship through an intermediate model. Join table attributes are a nice hack for someone who does not want to rewrite their application code to introduce the intermediate Model class.

In some cases, such as self-referential many-many associations, or when you are in the early stages of designing the schema and the application, you may find it appealing to manage the join table as a first-class Model. If so, then has_many_through will help you.

Here is a pattern that is now enabled easily by the new code. A Person is friends with many other People. They in turn are friends with other People. Friendship is directed, that is, A might think B is a friend, but B might not consider A as friend.

In doing this, it was easy to apply a simplified version of the Migrator mechanism using a new class called Relater.

For our example, we will have two models, a Person and Relationship. Follow the links to see the full source code on github.

The key thing that enables this is the new declarative style of specifying associations and their options.

  public dynamic class Person extends Modeler {
     private static const relations:Relater = new Relater(Person,
        function(me:Relater):void {
            me.hasMany('friendships', {
                  foreign_key: 'from_id',
                  class_name: 'example.Relationship'
            });
            me.hasMany('friends', {
                  through: 'friendships',
                  foreign_key: 'to_id',
                  class_name: 'example.Person'
            });
       });
     // migrations and other class code follows
   }

An added benefit of using this association mechanism is you don’t have to remember setting external compiler properties. The association look-up is faster as it involves a single access on a prototype member, as opposed to fetching and iterating through class meta-data. Internally, the new Relater seamlessly maintains the various Associators for Modeler objects, and allows backward compatibility. So the old style meta-data based declarations in existing code will still work.

Have fun and make many associations through AirDB!

Tue, 18 May 10