165 lines
4.9 KiB
Plaintext
165 lines
4.9 KiB
Plaintext
---
|
||
description: 'Learn how to create an entity in Medusa. This guide also explains how to create a repository and access and delete the entity.'
|
||
addHowToData: true
|
||
---
|
||
|
||
import Tabs from '@theme/Tabs';
|
||
import TabItem from '@theme/TabItem';
|
||
|
||
# How to Create an Entity
|
||
|
||
In this document, you’ll learn how you can create a custom [Entity](./overview.mdx).
|
||
|
||
## Step 1: Create the Entity
|
||
|
||
To create an entity, create a TypeScript file in `src/models`. For example, here’s a `Post` entity defined in the file `src/models/post.ts`:
|
||
|
||
:::note
|
||
|
||
Entities can only be placed in the top level of the `src/models` directory. So, you can't create an entity in a subfolder.
|
||
|
||
:::
|
||
|
||
```ts title="src/models/post.ts"
|
||
import {
|
||
BeforeInsert,
|
||
Column,
|
||
Entity,
|
||
PrimaryColumn,
|
||
} from "typeorm"
|
||
import { BaseEntity } from "@medusajs/medusa"
|
||
import { generateEntityId } from "@medusajs/medusa/dist/utils"
|
||
|
||
@Entity()
|
||
export class Post extends BaseEntity {
|
||
@Column({ type: "varchar" })
|
||
title: string | null
|
||
|
||
@BeforeInsert()
|
||
private beforeInsert(): void {
|
||
this.id = generateEntityId(this.id, "post")
|
||
}
|
||
}
|
||
```
|
||
|
||
This entity has one column `title` defined. However, since it extends `BaseEntity` it will also have the `id`, `created_at`, and `updated_at` columns.
|
||
|
||
Medusa’s core entities all have the following format for IDs: `<PREFIX>_<RANDOM>`. For example, an order might have the ID `order_01G35WVGY4D1JCA4TPGVXPGCQM`.
|
||
|
||
To generate an ID for your entity that matches the IDs generated for Medusa’s core entities, you should add a `BeforeInsert` event handler. Then, inside that handler use Medusa’s utility function `generateEntityId` to generate the ID. It accepts the ID as a first parameter and the prefix as a second parameter. The `Post` entity IDs will be of the format `post_<RANDOM>`.
|
||
|
||
You can learn more about what decorators and column types you can use in [Typeorm’s documentation](https://typeorm.io/entities).
|
||
|
||
### Soft-Deletable Entities
|
||
|
||
If you want the entity to also be soft deletable then it should extend `SoftDeletableEntity` instead:
|
||
|
||
```ts
|
||
import { SoftDeletableEntity } from "@medusajs/medusa"
|
||
|
||
@Entity()
|
||
export class Post extends SoftDeletableEntity {
|
||
// ...
|
||
}
|
||
```
|
||
|
||
### Adding Relations
|
||
|
||
Your entity may be related to another entity. You can showcase the relation with [Typeorm's relation decorators](https://typeorm.io/relations).
|
||
|
||
For example, you can create another entity `Author` and add a `ManyToOne` relation to it from the `Post`, and a `OneToMany` relation from the `Author` to the `Post`:
|
||
|
||
<Tabs groupId="files" isCodeTabs={true}>
|
||
<TabItem value="post" label="src/models/post.ts" default>
|
||
|
||
```ts
|
||
import {
|
||
BeforeInsert,
|
||
Column,
|
||
Entity,
|
||
JoinColumn,
|
||
ManyToOne,
|
||
} from "typeorm"
|
||
import { BaseEntity } from "@medusajs/medusa"
|
||
import { generateEntityId } from "@medusajs/medusa/dist/utils"
|
||
import { Author } from "./author"
|
||
|
||
@Entity()
|
||
export class Post extends BaseEntity {
|
||
@Column({ type: "varchar" })
|
||
title: string | null
|
||
|
||
@Column({ type: "varchar" })
|
||
author_id: string
|
||
|
||
@ManyToOne(() => Author, (author) => author.posts)
|
||
@JoinColumn({ name: "author_id" })
|
||
author: Author
|
||
|
||
@BeforeInsert()
|
||
private beforeInsert(): void {
|
||
this.id = generateEntityId(this.id, "post")
|
||
}
|
||
}
|
||
```
|
||
|
||
</TabItem>
|
||
<TabItem value="author" label="src/models/author.ts">
|
||
|
||
```ts
|
||
import { BaseEntity, generateEntityId } from "@medusajs/medusa"
|
||
import {
|
||
BeforeInsert,
|
||
Column,
|
||
Entity,
|
||
OneToMany,
|
||
} from "typeorm"
|
||
import { Post } from "./post"
|
||
|
||
@Entity()
|
||
export class Author extends BaseEntity {
|
||
@Column({ type: "varchar" })
|
||
name: string
|
||
|
||
@Column({ type: "varchar", nullable: true })
|
||
image?: string
|
||
|
||
@OneToMany(() => Post, (post) => post.author)
|
||
posts: Post[]
|
||
|
||
@BeforeInsert()
|
||
private beforeInsert(): void {
|
||
this.id = generateEntityId(this.id, "auth")
|
||
}
|
||
}
|
||
```
|
||
|
||
</TabItem>
|
||
</Tabs>
|
||
|
||
Adding these relations allows you to later on expand these relations when retrieving records of this entity with repositories.
|
||
|
||
---
|
||
|
||
## Step 2: Create and Run Migrations
|
||
|
||
Additionally, you must create a migration for your entity. Migrations are used to update the database schema with new tables or changes to existing tables.
|
||
|
||
You can learn more about Migrations, how to create or generate them, and how to run them in the [Migration documentation](./migrations/create.md).
|
||
|
||
Make sure to run the migrations before you start using the entity.
|
||
|
||
---
|
||
|
||
## Advanced Entity Definitions
|
||
|
||
With entities, you can create relationships, index keys, and more. As Medusa uses Typeorm, you can learn about using these functionalities through [Typeorm's documentation](https://typeorm.io/entities).
|
||
|
||
---
|
||
|
||
## See Also
|
||
|
||
- [How to use repositories](./repositories.md)
|
||
- [Extend an entity](./extend-entity.md)
|
||
- [Create a plugin](../plugins/create.mdx)
|