Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inverse relation support for CBLModel #606

Closed
snej opened this issue Feb 20, 2015 · 2 comments · Fixed by #607
Closed

Inverse relation support for CBLModel #606

snej opened this issue Feb 20, 2015 · 2 comments · Fixed by #607
Assignees
Milestone

Comments

@snej
Copy link
Contributor

snej commented Feb 20, 2015

Add CBLModel support for computed inverse-relation properties (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 it should be possible to define 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 querying a view that indexes the artist property of every album document. (If this turns out to be too slow we can cache the value until the view index changes.)

Caveats:

  • The property value is recomputed on every call.
  • 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.)

To define a property like this, you have to do three things:

  1. Define the [dynamic] property itself, with type NSArray*.
  2. Implement a class method +propertyItemClass that returns the class that has the inverse relation, i.e. the class of the items in the array to be returned.
  3. Implement a class method +propertyInverseRelation that returns a string naming the relation property in the other class that should be queried.

In the example:

@interface Artist
    @property (readonly) NSArray* albums;
    ...

@implementation Artist
    ...
    @dynamic albums;
    + (Class) albumsItemClass { return [Album class]; }
    + (NSString*) albumsInverseRelation { return @"artist"; }
    ...
@snej snej added this to the 1.1.0 milestone Feb 20, 2015
@snej snej self-assigned this Feb 20, 2015
@snej
Copy link
Contributor Author

snej commented Feb 20, 2015

It's also possible to query the inverse relation explicitly, by calling:

/** Follows an _inverse_ relationship: returns the other models in the database that have a
    property named `inverseProperty` that points to this object. For example, if model class
    ListItem has a property 'list' that's a relation to a List model, then calling this method
    on a List instance, with relation 'list', will return all the ListItems that refer to this List.

    Specifically, what this does is run a CBLQuery that finds documents whose `relation`
    property value is equal to the document ID of the receiver. (And if `fromClass` is given,
    it's restricted to documents whose `type` property is one of the ones mapped to `fromClass`
    in the CBLModelFactory.)
    @param relation  The property name to look at
    @param fromClass  (Optional) The CBLModel subclass to restrict the search to.
    @return  An array of model objects found, or nil on error. */
- (NSArray*) findInverseOfRelation: (NSString*)relation
                         fromClass: (nullable Class)fromClass;

snej added a commit that referenced this issue Feb 20, 2015
* -[CBLModel findInverseOfRelation:fromClass:] explicitly computes an
  inverse relation.
* An array-of-models-valued property can be declared as a computed
  inverse relation by overriding +inverseRelationForArrayProperty or by
  implementing +{property}InverseRelation. (See doc-comments)

Fixes #606
snej added a commit that referenced this issue Feb 20, 2015
* -[CBLModel findInverseOfRelation:fromClass:] explicitly computes an
  inverse relation.
* An array-of-models-valued property can be declared as a computed
  inverse relation by overriding +inverseRelationForArrayProperty or by
  implementing +{property}InverseRelation. (See doc-comments)

Fixes #606
@snej
Copy link
Contributor Author

snej commented Jun 13, 2015

I've added a wiki page with an expanded version of the description above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant