We have that a Todo
belongsTo
a TodoList
and a TodoList
hasMany
Todo
s. Another type of
relation we can add is hasOne
. To do so, let’s add
TodoListImage
such that each TodoList
hasOne
image. In parallel, a
TodoListImage
will belong to a TodoList
, similar to how a Todo
belongs to
TodoList
.
Create the Model
Similar to how we created the model for
TodoList
, using lb4 model
:
lb4 model
? Model class name: TodoListImage
? Please select the model base class Entity (A persisted model with an ID)
? Allow additional (free-form) properties? No
Model TodoListImage will be created in src/models/todo-list-image.model.ts
Let's add a property to TodoListImage
Enter an empty property name when done
? Enter the property name: id
? Property type: number
? Is id the ID property? Yes
? Is id generated automatically? No
? Is it required?: No
? Default value [leave blank for none]:
Let's add another property to TodoListImage
Enter an empty property name when done
? Enter the property name: value
? Property type: string
? Is it required?: Yes
? Default value [leave blank for none]:
Let's add another property to TodoListImage
Enter an empty property name when done
? Enter the property name:
create src/models/todo-list-image.model.ts
update src/models/index.ts
Model TodoListImage was created in src/models/
Create the Repository
Using lb4 repository
, let’s create the repository:
lb4 repository
? Please select the datasource DbDatasource
? Select the model(s) you want to generate a repository TodoListImage
? Please select the repository base class DefaultCrudRepository (Juggler bridge)
create src/repositories/todo-list-image.repository.ts
update src/repositories/index.ts
Repository TodoListImageRepository was created in src/repositories/
Create the Controller
Using lb4 controller
, let’s create the controller:
$ lb4 controller
? Controller class name: TodoListImage
Controller TodoListImage will be created in src/controllers/todo-list-image.controller.ts
? What kind of controller would you like to generate? REST Controller with CRUD functions
? What is the name of the model to use with this CRUD repository? TodoListImage
? What is the name of your CRUD repository? TodoListImageRepository
? What is the name of ID property? id
? What is the type of your ID? number
? Is the id omitted when creating a new instance? Yes
? What is the base HTTP path name of the CRUD operations? /todo-list-images
create src/controllers/todo-list-image.controller.ts
update src/controllers/index.ts
Controller TodoListImage was created in src/controllers/
Add the Relation
Adding a hasOne
relation is similar to the HasMany
relation. Let’s use the lb4 relation
command.
$ lb4 relation
? Please select the relation type hasOne
? Please select source model TodoList
? Please select target model TodoListImage
? Foreign key name to define on the target model todoListId
? Source property name for the relation getter (will be the relation name) image
? Allow TodoList queries to include data from related TodoListImage instances? Yes
create src/controllers/todo-list-todo-list-image.controller.ts
Relation HasOne was created in src/
Now, we’re going to add the relation for TodoListImage
. That is,
TodoListImage
belongsTo TodoList
:
$ lb4 relation
? Please select the relation type belongsTo
? Please select source model TodoListImage
? Please select target model TodoList
? Foreign key name to define on the source model todoListId
? Relation name todoList
? Allow TodoListImage queries to include data from related TodoList instances? Yes
create src/controllers/todo-list-image-todo-list.controller.ts
Relation BelongsTo was created in src/
As you can see, this created the relational controllers
todo-list-todo-list-image.controller.ts
and
todo-list-image-todo-list.controller.ts
.
As src/controllers/todo-list-image-todo-list.controller.ts only contains one method, we can move it to the TodoListImage controller and delete that file:
import {repository} from '@loopback/repository';
import {param, get, getModelSchemaRef} from '@loopback/rest';
import {TodoListImage, TodoList} from '../models';
import {TodoListImageRepository} from '../repositories';
export class TodoListImageController {
constructor() {} // ...
// other controller methods
@get('/todo-list-images/{id}/todo-list', {
responses: {
'200': {
description: 'TodoList belonging to TodoListImage',
content: {
'application/json': {
schema: {type: 'array', items: getModelSchemaRef(TodoList)},
},
},
},
},
})
async getTodoList(
@param.path.number('id') id: typeof TodoListImage.prototype.id,
): Promise<TodoList> {
return this.todoListImageRepository.todoList(id);
}
}
Then you should see the new added property image
is decorated with the
decorator @hasOne
in the TodoList
to represent the TodoListImage
this
TodoList
has:
import {hasOne} from '@loopback/repository';
import {
TodoListImage,
TodoListImageWithRelations,
} from './todo-list-image.model';
@model()
export class TodoList extends Entity {
// ... other properties
@hasOne(() => TodoListImage)
image: TodoListImage;
// ...
}
export interface TodoListRelations {
todos?: TodoWithRelations[];
// Add the following line
image?: TodoListImageWithRelations;
}
If you check the TodoListImage
model, you will find that the foreign key
todoListId
is being added and decorated with @belongsTo
:
import {belongsTo} from '@loopback/repository';
import {TodoList, TodoListWithRelations} from './todo-list.model';
@model()
export class TodoListImage extends Entity {
// ... other properties
@belongsTo(() => TodoList)
todoListId: number;
// ...
}
export interface TodoListImageRelations {
todoList?: TodoListWithRelations;
}
Try to create instances and traverse the data as what we showed in the previous step yourself!
Note:
A hasOne
relation from model A to model B does not need a belongsTo
relation to exist from model B to model A.
Note:
See the @hasOne
and @belongsTo
documentation for more information on how to customize the decorators.
Navigation
Previous step: Add TodoList Relations
Last step: Add TodoList Controller