Skip to content

Commit

Permalink
feat: add navigational properties to find* methods
Browse files Browse the repository at this point in the history
Updated find* methods to include navigational properties, introduced *Relations to models, and updated DefaultCrudRepository to include Relations

Co-authored-by: Miroslav Bajtoš <mbajtoss@gmail.com>
  • Loading branch information
nabdelgadir and bajtos committed Jun 1, 2019
1 parent 87cf4ca commit 1f0aa0b
Show file tree
Hide file tree
Showing 34 changed files with 270 additions and 81 deletions.
25 changes: 22 additions & 3 deletions docs/site/BelongsTo-relation.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ export class Order extends Entity {
super(data);
}
}

export interface OrderRelations {
// describe navigational properties here
}

export type OrderWithRelations = Order & OrderRelations;
```

The definition of the `belongsTo` relation is inferred by using the `@belongsTo`
Expand All @@ -83,6 +89,10 @@ class Order extends Entity {
@belongsTo(() => Customer, {keyTo: 'pk'})
customerId: number;
}

export interface OrderRelations {
customer?: CustomerWithRelations;
}
```

## Configuring a belongsTo relation
Expand Down Expand Up @@ -120,12 +130,13 @@ import {
juggler,
repository,
} from '@loopback/repository';
import {Customer, Order} from '../models';
import {Customer, Order, OrderRelations} from '../models';
import {CustomerRepository} from '../repositories';

export class OrderRepository extends DefaultCrudRepository<
Order,
typeof Order.prototype.id
typeof Order.prototype.id,
OrderRelations
> {
public readonly customer: BelongsToAccessor<
Customer,
Expand Down Expand Up @@ -212,14 +223,22 @@ export class Category extends Entity {
super(data);
}
}

export interface CategoryRelations {
categories?: CategoryWithRelations[];
parent?: CategoryWithRelations;
}

export type CategoryWithRelations = Category & CategoryRelations;
```

The `CategoryRepository` must be declared like below

```ts
export class CategoryRepository extends DefaultCrudRepository<
Category,
typeof Category.prototype.id
typeof Category.prototype.id,
CategoryRelations
> {
public readonly parent: BelongsToAccessor<
Category,
Expand Down
19 changes: 16 additions & 3 deletions docs/site/HasMany-relation.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ export class Order extends Entity {
super(data);
}
}

export interface OrderRelations {
// describe navigational properties here
}

export type OrderWithRelations = Order & OrderRelations;
```

The foreign key property (`customerId`) in the target model can be added via a
Expand All @@ -140,7 +146,7 @@ corresponding [belongsTo](BelongsTo-relation.md) relation, too.

```ts
import {Entity, model, property, belongsTo} from '@loopback/repository';
import {Customer} from './customer.model';
import {Customer, CustomerWithRelations} from './customer.model';

@model()
export class Order extends Entity {
Expand All @@ -164,6 +170,12 @@ export class Order extends Entity {
super(data);
}
}

export interface OrderRelations {
customer?: CustomerWithRelations;
}

export type OrderWithRelations = Order & OrderRelations;
```

## Configuring a hasMany relation
Expand Down Expand Up @@ -195,7 +207,7 @@ The following code snippet shows how it would look like:
content="/src/repositories/customer.repository.ts" %}

```ts
import {Order, Customer} from '../models';
import {Order, Customer, CustomerRelations} from '../models';
import {OrderRepository} from './order.repository';
import {
DefaultCrudRepository,
Expand All @@ -207,7 +219,8 @@ import {inject, Getter} from '@loopback/core';

export class CustomerRepository extends DefaultCrudRepository<
Customer,
typeof Customer.prototype.id
typeof Customer.prototype.id,
CustomerRelations
> {
public readonly orders: HasManyRepositoryFactory<
Order,
Expand Down
5 changes: 3 additions & 2 deletions docs/site/Repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,14 @@ TypeScript version:

```ts
import {DefaultCrudRepository, juggler} from '@loopback/repository';
import {Account} from '../models';
import {Account, AccountRelations} from '../models';
import {DbDataSource} from '../datasources';
import {inject} from '@loopback/context';

export class AccountRepository extends DefaultCrudRepository<
Account,
typeof Account.prototype.id
typeof Account.prototype.id,
AccountRelations
> {
constructor(@inject('datasources.db') dataSource: DbDataSource) {
super(Account, dataSource);
Expand Down
21 changes: 17 additions & 4 deletions docs/site/hasOne-relation.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ defined on a source model `Supplier` in the example below:
{% include code-caption.html content="/src/models/supplier.model.ts" %}

```ts
import {Account} from './account.model';
import {Account, AccountWithRelations} from './account.model';
import {Entity, property, hasOne} from '@loopback/repository';

export class Supplier extends Entity {
Expand All @@ -80,13 +80,19 @@ export class Supplier extends Entity {
super(data);
}
}

export interface SupplierRelations {
account?: AccountWithRelations;
}

export type SupplierWithRelations = Supplier & SupplierRelations;
```

On the other side of the relation, we'd need to declare a `belongsTo` relation
since every `Account` has to belong to exactly one `Supplier`:

```ts
import {Supplier} from './supplier.model';
import {Supplier, SupplierWithRelations} from './supplier.model';
import {Entity, property, belongsTo} from '@loopback/repository';

export class Account extends Entity {
Expand All @@ -108,6 +114,12 @@ export class Account extends Entity {
super(data);
}
}

export interface AccountRelations {
supplier?: SupplierWithRelations;
}

export type AccountWithRelations = Account & AccountRelations;
```

The definition of the `hasOne` relation is inferred by using the `@hasOne`
Expand Down Expand Up @@ -190,7 +202,7 @@ The following code snippet shows how it would look like:
content="/src/repositories/supplier.repository.ts" %}

```ts
import {Account, Supplier} from '../models';
import {Account, Supplier, SupplierRelations} from '../models';
import {AccountRepository} from './account.repository';
import {
DefaultCrudRepository,
Expand All @@ -202,7 +214,8 @@ import {inject, Getter} from '@loopback/core';

export class SupplierRepository extends DefaultCrudRepository<
Supplier,
typeof Supplier.prototype.id
typeof Supplier.prototype.id,
SupplierRelations
> {
public readonly account: HasOneRepositoryFactory<
Account,
Expand Down
14 changes: 13 additions & 1 deletion docs/site/tutorials/todo-list/todo-list-tutorial-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ model. Add the following import statements and property to the `TodoList` model:

```ts
import {hasMany} from '@loopback/repository';
import {Todo} from './todo.model';
import {Todo, TodoWithRelations} from './todo.model';

@model()
export class TodoList extends Entity {
Expand All @@ -87,6 +87,12 @@ export class TodoList extends Entity {

// ...constructor def...
}

export interface TodoListRelations {
todos?: TodoWithRelations[];
}

export type TodoListWithRelations = TodoList & TodoListRelations;
```

The `@hasMany()` decorator defines this property. As the decorator's name
Expand All @@ -108,6 +114,12 @@ export class Todo extends Entity {

// ...constructor def...
}

export interface TodoRelations {
todoList?: TodoListWithRelations;
}

export type TodoWithRelations = Todo & TodoRelations;
```

Once the models have been completely configured, it's time to move on to adding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,13 @@ import {
juggler,
repository,
} from '@loopback/repository';
import {Todo, TodoList} from '../models';
import {Todo, TodoList, TodoListRelations} from '../models';
import {TodoRepository} from './todo.repository';
export class TodoListRepository extends DefaultCrudRepository<
TodoList,
typeof TodoList.prototype.id
typeof TodoList.prototype.id,
TodoListRelations
> {
public readonly todos: HasManyRepositoryFactory<
Todo,
Expand Down
6 changes: 6 additions & 0 deletions examples/express-composition/src/models/note.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ export class Note extends Entity {
super(data);
}
}

export interface NoteRelations {
// describe navigational properties here
}

export type NoteWithRelations = Note & NoteRelations;
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {inject} from '@loopback/core';
import {DefaultCrudRepository} from '@loopback/repository';
import {Note} from '../models';
import {DsDataSource} from '../datasources';
import {inject} from '@loopback/core';
import {Note, NoteRelations} from '../models';

export class NoteRepository extends DefaultCrudRepository<
Note,
typeof Note.prototype.id
typeof Note.prototype.id,
NoteRelations
> {
constructor(@inject('datasources.ds') dataSource: DsDataSource) {
super(Note, dataSource);
Expand Down
10 changes: 8 additions & 2 deletions examples/todo-list/src/models/todo-list-image.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {Entity, model, property, belongsTo} from '@loopback/repository';
import {TodoList} from './todo-list.model';
import {belongsTo, Entity, model, property} from '@loopback/repository';
import {TodoList, TodoListWithRelations} from './todo-list.model';

@model()
export class TodoListImage extends Entity {
Expand All @@ -29,3 +29,9 @@ export class TodoListImage extends Entity {
super(data);
}
}

export interface TodoListImageRelations {
todoList?: TodoListWithRelations;
}

export type TodoListImageWithRelations = TodoListImage & TodoListImageRelations;
16 changes: 13 additions & 3 deletions examples/todo-list/src/models/todo-list.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {Entity, model, property, hasMany, hasOne} from '@loopback/repository';
import {Todo} from './todo.model';
import {TodoListImage} from './todo-list-image.model';
import {Entity, hasMany, hasOne, model, property} from '@loopback/repository';
import {
TodoListImage,
TodoListImageWithRelations,
} from './todo-list-image.model';
import {Todo, TodoWithRelations} from './todo.model';

@model()
export class TodoList extends Entity {
Expand Down Expand Up @@ -36,3 +39,10 @@ export class TodoList extends Entity {
super(data);
}
}

export interface TodoListRelations {
todos?: TodoWithRelations[];
image?: TodoListImageWithRelations;
}

export type TodoListWithRelations = TodoList & TodoListRelations;
10 changes: 8 additions & 2 deletions examples/todo-list/src/models/todo.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {Entity, property, model, belongsTo} from '@loopback/repository';
import {TodoList} from './todo-list.model';
import {belongsTo, Entity, model, property} from '@loopback/repository';
import {TodoList, TodoListWithRelations} from './todo-list.model';

@model()
export class Todo extends Entity {
Expand Down Expand Up @@ -41,3 +41,9 @@ export class Todo extends Entity {
super(data);
}
}

export interface TodoRelations {
todoList?: TodoListWithRelations[];
}

export type TodoWithRelations = Todo & TodoRelations;
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
// Copyright IBM Corp. 2018. All Rights Reserved.
// Copyright IBM Corp. 2018,2019. All Rights Reserved.
// Node module: @loopback/example-todo-list
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {Getter, inject} from '@loopback/core';
import {
BelongsToAccessor,
DefaultCrudRepository,
repository,
BelongsToAccessor,
} from '@loopback/repository';
import {TodoListImage, TodoList} from '../models';
import {DbDataSource} from '../datasources';
import {inject, Getter} from '@loopback/core';
import {TodoList, TodoListImage, TodoListImageRelations} from '../models';
import {TodoListRepository} from './todo-list.repository';

export class TodoListImageRepository extends DefaultCrudRepository<
TodoListImage,
typeof TodoListImage.prototype.id
typeof TodoListImage.prototype.id,
TodoListImageRelations
> {
public readonly todoList: BelongsToAccessor<
TodoList,
Expand Down
9 changes: 5 additions & 4 deletions examples/todo-list/src/repositories/todo-list.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ import {Getter, inject} from '@loopback/core';
import {
DefaultCrudRepository,
HasManyRepositoryFactory,
HasOneRepositoryFactory,
juggler,
repository,
HasOneRepositoryFactory,
} from '@loopback/repository';
import {Todo, TodoList, TodoListImage} from '../models';
import {TodoRepository} from './todo.repository';
import {Todo, TodoList, TodoListImage, TodoListRelations} from '../models';
import {TodoListImageRepository} from './todo-list-image.repository';
import {TodoRepository} from './todo.repository';

export class TodoListRepository extends DefaultCrudRepository<
TodoList,
typeof TodoList.prototype.id
typeof TodoList.prototype.id,
TodoListRelations
> {
public readonly todos: HasManyRepositoryFactory<
Todo,
Expand Down
Loading

0 comments on commit 1f0aa0b

Please sign in to comment.