Skip to content

Commit

Permalink
Merge d502022 into 0089084
Browse files Browse the repository at this point in the history
  • Loading branch information
nabdelgadir committed Jan 13, 2020
2 parents 0089084 + d502022 commit ee44435
Show file tree
Hide file tree
Showing 11 changed files with 302 additions and 144 deletions.
118 changes: 4 additions & 114 deletions docs/site/tutorials/todo-list/todo-list-tutorial-controller.md
Expand Up @@ -30,6 +30,7 @@ Controller TodoList will be created in src/controllers/todo-list.controller.ts
? What is the name of your CRUD repository? TodoListRepository
? 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-lists
create src/controllers/todo-list.controller.ts
update src/controllers/index.ts
Expand Down Expand Up @@ -193,119 +194,8 @@ export class TodoListTodoController {
```

Using our constraining factory as we did with the `POST` request, we'll define
the controller methods for the rest of the HTTP verbs for the route. The
completed controller should look as follows:

{% include code-caption.html content="src/controllers/todo-list-todo.controller.ts" %}

```ts
import {
Count,
CountSchema,
Filter,
repository,
Where,
} from '@loopback/repository';
import {
del,
get,
getModelSchemaRef,
getWhereSchemaFor,
param,
patch,
post,
requestBody,
} from '@loopback/rest';
import {Todo} from '../models';
import {TodoListRepository} from '../repositories';

export class TodoListTodoController {
constructor(
@repository(TodoListRepository) protected todoListRepo: TodoListRepository,
) {}

@post('/todo-lists/{id}/todos', {
responses: {
'200': {
description: 'TodoList.Todo model instance',
content: {'application/json': {schema: getModelSchemaRef(Todo)}},
},
},
})
async create(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Todo, {title: 'NewTodo', exclude: ['id']}),
},
},
})
todo: Omit<Todo, 'id'>,
): Promise<Todo> {
return this.todoListRepo.todos(id).create(todo);
}

@get('/todo-lists/{id}/todos', {
responses: {
'200': {
description: "Array of Todo's belonging to TodoList",
content: {
'application/json': {
schema: {type: 'array', items: getModelSchemaRef(Todo)},
},
},
},
},
})
async find(
@param.path.number('id') id: number,
@param.query.object('filter') filter?: Filter<Todo>,
): Promise<Todo[]> {
return this.todoListRepo.todos(id).find(filter);
}

@patch('/todo-lists/{id}/todos', {
responses: {
'200': {
description: 'TodoList.Todo PATCH success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async patch(
@param.path.number('id') id: number,
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Todo, {partial: true}),
},
},
})
todo: Partial<Todo>
@param.query.object('where', getWhereSchemaFor(Todo)) where?: Where<Todo>,
): Promise<Count> {
return this.todoListRepo.todos(id).patch(todo, where);
}

@del('/todo-lists/{id}/todos', {
responses: {
'200': {
description: 'TodoList.Todo DELETE success count',
content: {'application/json': {schema: CountSchema}},
},
},
})
async delete(
@param.path.number('id') id: number,
@param.query.object('where', getWhereSchemaFor(Todo)) where?: Where<Todo>,
): Promise<Count> {
return this.todoListRepo.todos(id).delete(where);
}
}
```

Check out our `TodoList` example to see the full source code generated for the
the controller methods for the rest of the HTTP verbs for the route. Check out
our `TodoList` example to see the full source code generated for the
`TodoListTodo` controller:
[src/controllers/todo-list-todo.controller.ts](https://github.com/strongloop/loopback-next/blob/master/examples/todo-list/src/controllers/todo-list-todo.controller.ts)

Expand Down Expand Up @@ -333,4 +223,4 @@ And there you have it! You now have the power to define APIs for related models!

### Navigation

Previous step: [Add TodoList repository](todo-list-tutorial-repository.md)
Previous step: [Add Model Relations](todo-list-tutorial-relations.md)
207 changes: 207 additions & 0 deletions docs/site/tutorials/todo-list/todo-list-tutorial-has-one-relation.md
@@ -0,0 +1,207 @@
---
lang: en
title: 'Add TodoListImage Relation'
keywords: LoopBack 4.0, LoopBack 4
sidebar: lb4_sidebar
permalink: /doc/en/lb4/todo-list-tutorial-has-one-relation.html
summary: LoopBack 4 TodoList Application Tutorial - Add TodoListImage Relation
---

We have that a `Todo` [`belongsTo`](../../BelongsTo-relation.md) a `TodoList`
and a `TodoList` [`hasMany`](../../HasMany-relation.md) `Todo`s. Another type of
relation we can add is [`hasOne`](../../hasOne-relation.md). To do so, let's add
`TodoListImage` such that each `TodoList` `hasOne` image.

### Create the Model

Similar to how we created the model for
[`TodoList`](todo-list-tutorial-model.md), using `lb4 model`:

```sh
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:

```sh
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 (Legacy juggler bridge)
create src/repositories/todo-list-image.repository.ts
update src/repositories/index.ts
Repository TodoListImageRepository was created in src/repositories/
```
### Add the Relation
First, let's add the relation to the model classes:
{% include code-caption.html content="src/models/todo-list-image.model.ts" %}
```ts
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;
}
```
{% include code-caption.html content="src/models/todo-list.model.ts" %}
```ts
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;
}
```
Next, let's add the relation to the repository classes:
{% include code-caption.html content="src/repositories/todo-list.repository.ts" %}
```ts
// Add the following imports
import {HasOneRepositoryFactory} from '@loopback/repository';
import {TodoListImage} from '../models';
import {TodoListImageRepository} from './todo-list-image.repository';
export class TodoListRepository extends DefaultCrudRepository<
TodoList,
typeof TodoList.prototype.id,
TodoListRelations
> {
// other code
// Add the following
public readonly image: HasOneRepositoryFactory<
TodoListImage,
typeof TodoList.prototype.id
>;
constructor(
// other code
// Add the following
@repository.getter('TodoListImageRepository')
protected todoListImageRepositoryGetter: Getter<TodoListImageRepository>,
) {
// other code
// Add the following
this.image = this.createHasOneRepositoryFactoryFor(
'image',
todoListImageRepositoryGetter,
);
this.registerInclusionResolver('image', this.image.inclusionResolver);
}
}
```
```ts
import {BelongsToAccessor} from '@loopback/repository';
import {TodoList} from '../models';
import {TodoListRepository} from './todo-list.repository';
export class TodoListImageRepository extends DefaultCrudRepository<
TodoListImage,
typeof TodoListImage.prototype.id,
TodoListImageRelations
> {
// Add the following
public readonly todoList: BelongsToAccessor<
TodoList,
typeof TodoListImage.prototype.id
>;
constructor(
// other code
// Add the following line
protected todoListRepositoryGetter: Getter<TodoListRepository>,
) {
// other code
// Add the following
this.todoList = this.createBelongsToAccessorFor(
'todoList',
todoListRepositoryGetter,
);
this.registerInclusionResolver('todoList', this.todoList.inclusionResolver);
}
}
```
{% include note.html content="
We are working on adding `hasOne` to the CLI command `lb4 relation`. See [issue #2980](https://github.com/strongloop/loopback-next/issues/2980).
" %}
### Navigation
Previous step: [Add Model Relations](todo-list-tutorial-relations.md)
Last step: [Add TodoList Controller](todo-list-tutorial-controller.md)
8 changes: 4 additions & 4 deletions docs/site/tutorials/todo-list/todo-list-tutorial-model.md
Expand Up @@ -31,7 +31,7 @@ for us as follows:
```sh
$ lb4 model
? Model class name: TodoList
? Please select the model base class Entity
? Please select the model base class Entity (A persisted model with an ID)
? Allow additional (free-form) properties? No
Model TodoList will be created in src/models/todo-list.model.ts

Expand All @@ -41,22 +41,22 @@ 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? Yes
? Is id generated automatically? No
Let's add another property to TodoList
Enter an empty property name when done

? Enter the property name: title
? Property type: string
? Required?: Yes
? Is it required?: Yes
? Default value [leave blank for none]:

Let's add another property to TodoList
Enter an empty property name when done
? Enter the property name: color
? Property type: string
? Required?: No
? Is it required?: No
? Default value [leave blank for none]:
Let's add another property to TodoList
Expand Down

0 comments on commit ee44435

Please sign in to comment.