-
Notifications
You must be signed in to change notification settings - Fork 297
Inverse Relationships
In Couchbase Lite 1.1, CBLModel now supports computed inverse-relation properties. This is a typical ORM feature, also found in Core Data.
For example, if the Album
class has a relation @property Artist* artist
(i.e. the JSON property value is the docID of a document corresponding to an Artist
model), then you can create a property on Artist
like @property (readonly) NSArray* albums
, whose value is an array of the Album
objects whose artist
property points to the receiver.
Behind the scenes, there's no JSON property backing this. Its value is computed on demand by creating and querying a view that indexes the artist
property of every album document.
- At launch time, register the document
type
property of both model classes with the database'sModelFactory
. - Define the
@property
in the class interface. It must be a read-onlyNSArray*
. - In the class implementation, declare the property as
@dynamic
. - Implement a class method +property
ItemClass
that returns the class that has the inverse relation, i.e. the class of the items in the array to be returned. - Implement a class method +property
InverseRelation
that returns a string naming the relation property in the other class that should be queried.
As in the introduction above, assume there is an Album
class that has a regular relation @property Artist* artist
(i.e. the JSON property value is the docID of a document corresponding to an Artist
model.) We then create the inverse relation as follows:
@interface Artist
@property (readonly) NSArray* albums;
...
@implementation Artist
...
@dynamic albums;
+ (Class) albumsItemClass { return [Album class]; }
+ (NSString*) albumsInverseRelation { return @"artist"; }
...
At runtime we register the document types:
[database.modelFactory registerClass: [Album class] forDocumentType: @"album"];
[database.modelFactory registerClass: [Artist class] forDocumentType: @"artist"];
- The property value is recomputed on every call. Database queries are not cheap, so accessing the property too often could easily become a performance bottleneck. You may want to cache the value. In the future we could add caching to the framework (invalidating the cache when the view index changes.)
- These properties are not KV-observable (that would be great to add later, but it would require something like a LiveQuery, and would have to be carefully optimized to be scaleable.)