TypeORM By Example: Part 7
Wrapping up series with many-to-many relationships.

This article is part of a series starting with TypeORM By Example: Part 1.
The final example for this article is available for download.
Many-to-Many — Define
Let us say our todos can be categorized; a todo can be associated with any number of categories and categories can be used across multiple todos. We create:
src / entity / Category.ts
and update:
src / entity / Todo.ts
Observation:
- We have to identify one of the two entities, Category or Todo, as owning the relationship; in this case have the Todo own it.
With this in place, we build the application and generate the migration.
npm run build-ts
./node_modules/.bin/typeorm migration:generate -n Category
The migration.
src /migration / 1536009244697-Category.ts
And then building and starting the application:
npm run build-ts
npm run start
We now see that the migration runs and the tables are created / updated:

Observations:
- As expected, we have a new table, todo_categories_category, capturing the relationship between todos and categories
- The composite index, (todoId, categoryId), in addition to be a primary key will help with performance on lookups of categories of a certain todo.
- But, there is no separate index on categoryId; so lookups of todos of a certain category will have performance issues (assuming that there are a lot of todos). We will address later in the article.
Many-to-Many — Create
To illustrate the use of categories, we arrange it so that we create two categories if none exist and then use them for all created todos.
src / todoManager.ts
Many-to-Many — Read
We update the TodoRepository with the relations in both the find and QueryBuilder syntax to find categories given a todo.
src / TodoRepository.ts
Observations:
- With the QueryBuilder we are required to use a left-join as categories are optional for todos
- Also, happened to notice a bug in the earlier versions of the QueryBuilder code; they were not mapping the name
with a result of:

Many-to-Many — Read (Reverse)
Say, we wanted to know all the todos with a particular category. We need to update the entities with bi-directional relations.
src / entity / Category.ts
src / entity / Todo.ts
With these updates we can query categories with relations.
src / categoryManager.ts
src / server.ts
with the result of:

Foreign-Key Index
Much like the one-to-many example, we are missing an index to optimize queries where we have a lot of todos and looking for todos with a specific category.
After a number of attempts, I did not find any way to create the necessary index on the join table. So, went ahead and manually created a migration.
./node_modules/.bin/typeorm migration:create -n CategoryIndex
and update it.
src / migration / 1536025479273-CategoryIndex.ts
then we build and start the application
npm run build-ts
npm run start
and see that the index was built.

The problem (reported as a question), however, is that every time we want to generate a new migration that migration will try to delete this index in addition to the desired behavior.
Wrap Up
This series ended up being way longer than expected. Actually kind of glad I am done (hopefully).
Enjoy!