From c54503319fd17960d1406e13c99c8b07f67ecda0 Mon Sep 17 00:00:00 2001 From: Agnes Lin Date: Tue, 10 Sep 2019 19:26:02 -0400 Subject: [PATCH] docs: add docs for inclusion resolver for has many --- docs/site/HasMany-relation.md | 113 ++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/docs/site/HasMany-relation.md b/docs/site/HasMany-relation.md index dcf1353eb6c5..e8f24c4ee4ff 100644 --- a/docs/site/HasMany-relation.md +++ b/docs/site/HasMany-relation.md @@ -314,3 +314,116 @@ certain properties from the JSON/OpenAPI spec schema built for the `requestBody` payload. See its [GitHub issue](https://github.com/strongloop/loopback-next/issues/1179) to follow the discussion. " %} + +## Querying related models + +Loopback4 has the concept of `inclusion resolver` in relations, which helps to +query data through include filter. An inclusion resolver is a function that can +fetch target models for the given list of source model instances. LB4 creates a +different inclusion resolver for each relation type. + +The following is an example for has-many inclusion resolver: + +- Model `Customer` +- Model `Order` +- `Customer` has mamy `Order` + +```ts +// import statements +class Customer extends Entity { + // property definition for id, name + @hasMany(() => Order, {keyTo: 'customerId'}) + orders?: Order[]; +} +``` + +```ts +// import statements +class Order extends Entity { + // property definition for id, name + @property({ + type: 'number', + }) + customerId?: number; + // constructor, relation, etc +} +``` + +The inclusion resolver allows users to retrieve all customer along with all +related orders by the following code: + +```ts +categoryRepo.find({include: [{relation: 'products'}]}); +``` + +### Enable/disable the inclusion resolvers: + +- Base repository classes have a public property `inclusionResolvers`, which + maintains a map containing inclusion resolvers for each relation. +- The inclusion resolver `inclusionResolver` of a certain relation is built when + the source repository class calls the `createHasManyRepositoryFactoryFor` + function in the constructor with the relation name. +- Call `registerInclusionResolver` to add the resolver of that relation to the + `inclusionResolvers` map. (As we realized in LB3, not all relations are + allowed to be traversed. Users can decide to which resolvers can be added.) + +The following code snippet shows how it would look like for registering the +inclusion resolver for has many relation 'orders': + +```ts +export class CustomerRepository extends DefaultCrudRepository { + products: HasManyRepositoryFactory; + + constructor( + dataSource: juggler.DataSource, + orderRepositoryGetter: Getter, + ) { + super(Customer, dataSource); + + // we already have this line to create HasManyRepository factory + this.orders = this.createHasManyRepositoryFactoryFor( + 'orders', + orderRepositoryGetter, + ); + + // add this line to register inclusion resolver + this.registerInclusion('orders', this.orders.inclusionResolver); + } +} +``` + +- We can simply include the relation in queries via find(), findOne(), + findById() methods. Example: + +``` +customerRepository.find({include: [{relation: 'orders'}]}); +``` + +which returns: + +```ts +[ + { + id: 1, + name: 'Thor', + orders:[{name: 'Mjolnir', customerId: 1}, {name: 'Rocket Raccoon', customerId: 1}] + }, + { + id: 2, + name: 'Captain', + orders:[{name: 'Shield', customerId: 2}] + }, + ... +] +``` + +- You can delete a relation from `inclusionResolvers` to disable the inclusion + for a certain relation. e.g + `customerRepository.inclusionResolvers.delete('orders')` + +{% include note.html content=" +Inclusion with custom scope: +Besides specifying the relation name to include, it's also possible to specify additional scope constraints. +However, this feature is not supported yet. Check our GitHub issue for more information: +[Include related models with a custom scope](https://github.com/strongloop/loopback-next/issues/3453). +" %}