Robert Mosolgo

To my knowledge, batman.js is not maintained. For that reason, I don't suggest that you use it for a new project!

Has Many Through in Batman.js

Batman.js doesn’t support hasManyThrough out of the box, but it can be implemented fairly easily with Set::mappedTo.

This feature was just merged into the master branch – download the latest batman.js here.

What’s a “Has-Many-Through” Association?

It’s best shown by example. To join Household to Person, you might have a “join model”, HouseholdMembership. The associations look like this:

1
2
3
4
5
6
7
8
9
class Household extends Batman.Model
  @hasMany 'householdMemberships'

class HouseholdMembership extends Batman.Model
  @belongsTo 'household'
  @belongsTo 'person'

class Person extends Batman.Model
  @hasMany 'householdMemberships'

Household hasMany memberships, each membership belongsTo a person.

1
2
3
4
5
           __ HouseholdMembership ─── Person
         
Household ─── HouseholdMembership ─── Person
         
           _ HouseholdMembership ─── Person

Household has many people through household memberships.

Has-Many-Through in Batman.js

Although hasManyThrough isn’t part of batman.js, you can implement a read-only has-many-through using Set::mappedTo. Given classes as defined above, you could add an accessor for Household::people:

1
2
# class Household
  @accessor 'people', -> @get('householdMemberships').mappedTo('person')

This returns a Batman.Set (actually a Batman.SetMapping) containing unique Persons belonging to those householdMemberships. As batman.js does, items added and removed are automatically tracked, so this is safe to use everywhere.

As for adding items, you could do it this way:

1
2
3
# class Household
  addPerson: (person) ->
    @get('householdMemberships').build({person})

Again, the Batman.SetMapping will take care of keeping everything in sync!