docs: updates to use DML and other changes (#7834)
- Change existing data model guides and add new ones for DML - Change module's docs around service factory + remove guides that are now necessary - Hide/remove all mentions of module relationships, or label them as coming soon. - Change all data model creation snippets to use DML - use `property` instead of `field` when referring to a data model's properties. - Fix all snippets in commerce module guides to use new method suffix (no more main model methods) - Rework recipes, removing/hiding a lot of sections as a lot of recipes are incomplete with the current state of DML. ### Other changes - Highlight fixes in some guides - Remove feature flags guide - Fix code block styles when there are no line numbers. ### Upcoming changes in other PRs - Re-generate commerce module references (for the updates in the method names) - Ensure that the data model references are generated correctly for models using DML. - (probably at a very later point) revisit recipes
This commit is contained in:
@@ -1,89 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Common Data Model Definitions`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you'll learn where to find resources on common data model definitions related to field's column types, relations, and indices.
|
||||
|
||||
## MikroORM Learning Resources
|
||||
|
||||
Refer to the following resources to learn about common definitions:
|
||||
|
||||
1. [Field column types](https://mikro-orm.io/docs/defining-entities).
|
||||
2. [Creating indices](https://mikro-orm.io/docs/defining-entities#indexes).
|
||||
|
||||
Refer to MikroORM's documentation for more details related to your use case.
|
||||
|
||||
---
|
||||
|
||||
## Relations Between Data Models
|
||||
|
||||
You can build relations between data models in the same module using foreign keys.
|
||||
|
||||
Refer to [MikroORM's relations definitions](https://mikro-orm.io/docs/relationships) for more details.
|
||||
|
||||
<Note>
|
||||
|
||||
For building relationships between data models in different modules, refer to the [Module Relationships chapter](../../modules/module-relationships/page.mdx) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Example Data Model
|
||||
|
||||
The following example showcase a data model with common definitions:
|
||||
|
||||
```ts collapsibleLines="1-10" expandButtonLabel="Show Imports"
|
||||
import {
|
||||
Entity,
|
||||
Enum,
|
||||
OneToOne,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { BaseEntity } from "@medusajs/utils"
|
||||
// assuming this is another implemented data model
|
||||
import ProductVariant from "./product-variant"
|
||||
|
||||
export enum MediaType {
|
||||
MAIN = "main",
|
||||
PREVIEW = "preview"
|
||||
}
|
||||
|
||||
@Entity()
|
||||
class ProductMedia extends BaseEntity {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
name: string
|
||||
|
||||
@Enum({ items: ["main", "preview"] })
|
||||
type: MediaType
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
file_key: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
mime_type: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
variant_id: string
|
||||
|
||||
@OneToOne({
|
||||
entity: ProductVariant,
|
||||
onDelete: "cascade",
|
||||
})
|
||||
variant: ProductVariant
|
||||
}
|
||||
|
||||
export default ProductMedia
|
||||
```
|
||||
|
||||
In the example above:
|
||||
|
||||
- The `ProductMedia` data model has the columns `id`, `name`, `type`, `file_key`, `mime_type`, and `variant_id`.
|
||||
- The data model has an index on the `variant_id` column.
|
||||
- The data model has a one-to-one relation to a `ProductVariant` data model.
|
||||
@@ -0,0 +1,84 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Configure Data Model Properties`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to configure data model properties, such as setting their default value.
|
||||
|
||||
## Property’s Default Value
|
||||
|
||||
Use the `default` method of the `model` utility to specify the default value of a property.
|
||||
|
||||
For example:
|
||||
|
||||
export const defaultHighlights = [
|
||||
["6", "default", "Set the default value to `black`."],
|
||||
["9", "default", "Set the default value to `0`."]
|
||||
]
|
||||
|
||||
```ts highlights={defaultHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
color: model
|
||||
.enum(["black", "white"])
|
||||
.default("black"),
|
||||
age: model
|
||||
.number()
|
||||
.default(0),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
In this example, you set the default value of the `color` enum property to `black`, and that of the `age` number property to `0`.
|
||||
|
||||
---
|
||||
|
||||
## Nullable Property
|
||||
|
||||
Use the `nullable` method to indicate that a property’s value can be `null`.
|
||||
|
||||
For example:
|
||||
|
||||
export const nullableHighlights = [
|
||||
["4", "nullable", "Configure the `price` property to allow `null` values."]
|
||||
]
|
||||
|
||||
```ts highlights={nullableHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
price: model.bigNumber().nullable(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Unique Property
|
||||
|
||||
The `unique` method indicates that a property’s value must be unique in the database.
|
||||
|
||||
For example:
|
||||
|
||||
export const uniqueHighlights = [
|
||||
["5", "unique", "Configure the `email` property to allow unique values only."]
|
||||
]
|
||||
|
||||
```ts highlights={uniqueHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const User = model.define("user", {
|
||||
email: model.text().unique(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default User
|
||||
```
|
||||
|
||||
In this example, multiple users can’t have the same email.
|
||||
@@ -0,0 +1,32 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Data Model Indexes`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to define indexes on a data model.
|
||||
|
||||
## Define Index
|
||||
|
||||
The `index` method defines a custom index on a property.
|
||||
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["5", "index", "Define an index on the `name` property."]
|
||||
]
|
||||
|
||||
```ts highlights={highlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
id: model.id(),
|
||||
name: model.text().index(
|
||||
"IDX_MY_CUSTOM_NAME"
|
||||
),
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
In this example, you define an index on the `name` property. The `index` method optionally accepts the name of the index as a parameter.
|
||||
@@ -0,0 +1,40 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Data Model’s Primary Key`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to configure the primary key of a data model.
|
||||
|
||||
## id Property
|
||||
|
||||
A property defined with the `id` method is, by default, considered the data model’s primary key.
|
||||
|
||||
---
|
||||
|
||||
## primaryKey Method
|
||||
|
||||
To set any `text` or `number` property as a primary key, use the `primaryKey` method.
|
||||
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["4", "primaryKey", "Define the `code` property to be the data model's primary key."]
|
||||
]
|
||||
|
||||
```ts highlights={highlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
code: model.text().primaryKey(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
A property that’s defined with the `primaryKey` method takes precedence over an `id` property.
|
||||
|
||||
</Note>
|
||||
@@ -0,0 +1,198 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Data Model Property Types`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn about the types of properties in a data model’s schema.
|
||||
|
||||
## id
|
||||
|
||||
The `id` method defines an automatically generated string ID property.
|
||||
|
||||
For example:
|
||||
|
||||
export const idHighlights = [["4", ".id()", "Define an `id` property."]]
|
||||
|
||||
```ts highlights={idHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
id: model.id(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
By default, this property is considered to be the data model’s primary key.
|
||||
|
||||
---
|
||||
|
||||
## text
|
||||
|
||||
The `text` method defines a string property.
|
||||
|
||||
For example:
|
||||
|
||||
export const textHighlights = [["4", "text", "Define a `text` property."]]
|
||||
|
||||
```ts highlights={textHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
name: model.text(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## number
|
||||
|
||||
The `number` method defines a number property.
|
||||
|
||||
For example:
|
||||
|
||||
export const numberHighlights = [["4", "number", "Define a `number` property."]]
|
||||
|
||||
```ts highlights={numberHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
age: model.number(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## bigNumber
|
||||
|
||||
The `bigNumber` method defines a number property that expects large numbers, such as prices.
|
||||
|
||||
For example:
|
||||
|
||||
export const bigNumberHighlights = [["4", "bigNumber", "Define a `bigNumber` property."]]
|
||||
|
||||
```ts highlights={bigNumberHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
price: model.bigNumber(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## boolean
|
||||
|
||||
The `boolean` method defines a boolean property.
|
||||
|
||||
For example:
|
||||
|
||||
export const booleanHighlights = [["4", "boolean", "Define a `boolean` property."]]
|
||||
|
||||
```ts highlights={booleanHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
hasAccount: model.boolean(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### enum
|
||||
|
||||
The `enum` method defines a property whose value can only be one of the specified values.
|
||||
|
||||
For example:
|
||||
|
||||
export const enumHighlights = [["4", "enum", "Define a `enum` property."]]
|
||||
|
||||
```ts highlights={enumHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
color: model.enum(["black", "white"]),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
The `enum` method accepts an array of possible string values.
|
||||
|
||||
---
|
||||
|
||||
## dateTime
|
||||
|
||||
The `dateTime` method defines a timestamp property.
|
||||
|
||||
For example:
|
||||
|
||||
export const dateTimeHighlights = [["4", "dateTime", "Define a `dateTime` property."]]
|
||||
|
||||
```ts highlights={dateTimeHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
date_of_birth: model.dateTime(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## json
|
||||
|
||||
The `json` method defines a property whose value is a stringified JSON object.
|
||||
|
||||
For example:
|
||||
|
||||
export const jsonHighlights = [["4", "json", "Define a `json` property."]]
|
||||
|
||||
```ts highlights={jsonHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
metadata: model.json(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## array
|
||||
|
||||
The `array` method defines an array or strings property.
|
||||
|
||||
For example:
|
||||
|
||||
export const arrHightlights = [["4", "array", "Define an `array` property."]]
|
||||
|
||||
```ts highlights={arrHightlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
names: model.array(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
@@ -0,0 +1,190 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Data Model Relationships`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to define relationships between data models in your module.
|
||||
|
||||
## What is a Relationship Property?
|
||||
|
||||
A relationship property is defined using relation methods, such as `hasOne` or `belongsTo`. It represents a relationship between two data models in a module.
|
||||
|
||||
---
|
||||
|
||||
## One-to-One Relationship
|
||||
|
||||
To define a one-to-one relationship, create relationship properties in the data models using the following methods:
|
||||
|
||||
1. `hasOne`: indicates that the model has one record of the specified model.
|
||||
2. `belongsTo`: indicates that the model belongs to one record of the specified model.
|
||||
|
||||
For example:
|
||||
|
||||
export const oneToOneHighlights = [
|
||||
["5", "hasOne", "A user has one email."],
|
||||
["10", "belongsTo", "An email belongs to a user."],
|
||||
["11", `"email"`, "The relationship's name in the `User` data model."]
|
||||
]
|
||||
|
||||
```ts highlights={oneToOneHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const User = model.define("user", {
|
||||
id: model.id(),
|
||||
email: model.hasOne(() => Email),
|
||||
})
|
||||
|
||||
const Email = model.define("email", {
|
||||
id: model.id(),
|
||||
user: model.belongsTo(() => User, {
|
||||
mappedBy: "email",
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
The `hasOne` and `belongsTo` methods accept a function as a first parameter. The function returns the associated data model.
|
||||
|
||||
The `belongsTo` method also requires passing as a second parameter an object with the property `mappedBy`. Its value is the name of the relationship property in the other data model.
|
||||
|
||||
In the example above, a user has one email, and an email belongs to one user.
|
||||
|
||||
---
|
||||
|
||||
## One-to-Many Relationship
|
||||
|
||||
To define a one-to-many relationship, create relationship properties in the data models using the following methods:
|
||||
|
||||
1. `hasMany`: indicates that the model has more than one records of the specified model.
|
||||
2. `belongsTo`: indicates that the model belongs to one record of the specified model.
|
||||
|
||||
For example:
|
||||
|
||||
export const oneToManyHighlights = [
|
||||
["5", "hasMany", "A store has many products"],
|
||||
["10", "belongsTo", "A product has one store."],
|
||||
["11", `"products"`, "The relationship's name in the `Store` data model."]
|
||||
]
|
||||
|
||||
```ts highlights={oneToManyHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const Store = model.define("store", {
|
||||
id: model.id(),
|
||||
products: model.hasMany(() => Product),
|
||||
})
|
||||
|
||||
const Product = model.define("product", {
|
||||
id: model.id(),
|
||||
store: model.belongsTo(() => Store, {
|
||||
mappedBy: "products",
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
In this example, a store has many products, but a product belongs to one store.
|
||||
|
||||
---
|
||||
|
||||
## Many-to-Many Relationship
|
||||
|
||||
To define a many-to-many relationship, create relationship properties in the data models using the `manyToMany` method.
|
||||
|
||||
For example:
|
||||
|
||||
export const manyToManyHighlights = [
|
||||
["5", "manyToMany", "An order is associated with many products."],
|
||||
["10", "manyToMany", "A product is associated with many orders."]
|
||||
]
|
||||
|
||||
```ts highlights={manyToManyHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const Order = model.define("order", {
|
||||
id: model.id(),
|
||||
products: model.manyToMany(() => Product),
|
||||
})
|
||||
|
||||
const Product = model.define("product", {
|
||||
id: model.id(),
|
||||
order: model.manyToMany(() => Order),
|
||||
})
|
||||
```
|
||||
|
||||
In this example, an order is associated with many products, and a product is associated with many orders.
|
||||
|
||||
---
|
||||
|
||||
## Configure Relationship Property Name
|
||||
|
||||
The relationship property methods accept as a second parameter an object of options. The `mappedBy` property defines the name of the relationship in the other data model.
|
||||
|
||||
As seen in previous examples, the `mappedBy` option is required for the `belongsTo` method.
|
||||
|
||||
For example:
|
||||
|
||||
export const relationNameHighlights = [
|
||||
["6", `"owner"`, "The relationship's name in the `Email` data model."],
|
||||
["13", `"email"`, "The relationship's name in the `User` data model."]
|
||||
]
|
||||
|
||||
```ts highlights={relationNameHighlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const User = model.define("user", {
|
||||
id: model.id(),
|
||||
email: model.hasOne(() => Email, {
|
||||
mappedBy: "owner",
|
||||
}),
|
||||
})
|
||||
|
||||
const Email = model.define("email", {
|
||||
id: model.id(),
|
||||
owner: model.belongsTo(() => User, {
|
||||
mappedBy: "email",
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
In this example, you specify in the `User` data model’s relationship property that the name of the relationship in the `Email` data model is `owner`.
|
||||
|
||||
This is useful if the relationship property’s name is different than that of the associated data model.
|
||||
|
||||
---
|
||||
|
||||
## Cascades
|
||||
|
||||
When an operation is performed on a data model, such as record deletion, the relationship cascade specifies what related data model records should be affected by it.
|
||||
|
||||
For example, if a store is deleted, its products should also be deleted.
|
||||
|
||||
The `cascades` method used on a data model configures which child records an operation is cascaded to.
|
||||
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["8", "", "When a store is deleted, delete its associated products."]
|
||||
]
|
||||
|
||||
```ts highlights={highlights}
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const Store = model.define("store", {
|
||||
id: model.id(),
|
||||
products: model.hasMany(() => Product),
|
||||
})
|
||||
.cascades({
|
||||
delete: ["products"],
|
||||
})
|
||||
|
||||
const Product = model.define("product", {
|
||||
id: model.id(),
|
||||
store: model.belongsTo(() => Store, {
|
||||
mappedBy: "products",
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
The `cascades` method accepts an object. Its key is the operation’s name, such as `delete`. The value is an array of relationship property names that the operation is cascaded to.
|
||||
|
||||
In the example above, when a store is deleted, its associated products are also deleted.
|
||||
@@ -0,0 +1,46 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Searchable Data Model Property`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you'll learn what a searchable property is and how to define it.
|
||||
|
||||
## What is a Searchable Property?
|
||||
|
||||
Methods generated by the [service factory](../../modules/service-factory/page.mdx) that accept filters, such as `list{ModelName}s`, accept a `q` property as part of the filters.
|
||||
|
||||
When the `q` filter is passed, the query is applied on searchable properties in a data model.
|
||||
|
||||
---
|
||||
|
||||
## Define a Searchable Property
|
||||
|
||||
The `searchable` method of the `model` utility indicates that a `text` property is searchable.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { model } from "@medusajs/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
name: model.text().searchable(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
In this example, the `name` property is searchable.
|
||||
|
||||
### Search Example
|
||||
|
||||
If you pass a `q` filter to the `listMyCustoms` method:
|
||||
|
||||
```ts
|
||||
const myCustoms = await helloModuleService.listMyCustoms({
|
||||
q: "John",
|
||||
})
|
||||
```
|
||||
|
||||
The `q` filter is applied on the `name` property of the `MyCustom` records.
|
||||
@@ -1,99 +1,19 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Soft-Deletable Models`,
|
||||
title: `${pageNumber} Soft-Deletable Data Models`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this document, you'll learn how to create soft-deletable data models.
|
||||
In this chapter, you’ll learn about soft-deletable data models.
|
||||
|
||||
## What is a Soft-Deletable Model?
|
||||
## What is a Soft-Deletable Data Model?
|
||||
|
||||
A soft-deletable data model is a model whose records aren't actually removed from the database when they're deleted.
|
||||
A soft-deletable data model is a model that has a `deleted_at` `dateTime` property.
|
||||
|
||||
Instead, their `deleted_at` field is set to the date the record was deleted.
|
||||
|
||||
When retrieving or listing records of that data model, records having their `deleted_at` field set aren't retrieved unless the `withDeleted` filter is provided.
|
||||
When a record of the data model is deleted, this field is set to the current date, marking it as deleted.
|
||||
|
||||
---
|
||||
|
||||
## How to Create a Soft-Deletable Model?
|
||||
## Configure Data Model Soft-Deletion
|
||||
|
||||
To create a soft-deletable model, first, add the following filter decorator to the data model class:
|
||||
|
||||
```ts title="src/module/hello/models/my-soft-deletable.ts" highlights={[["7"]]} collapsibleLines="1-7" expandButtonLabel="Show Imports"
|
||||
// other imports...
|
||||
import { Entity, Filter } from "@mikro-orm/core"
|
||||
import { DALUtils } from "@medusajs/utils"
|
||||
import { BaseEntity } from "@medusajs/utils"
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
class MySoftDeletable extends BaseEntity {
|
||||
// ...
|
||||
}
|
||||
|
||||
export default MySoftDeletable
|
||||
```
|
||||
|
||||
Then, add a `deleted_at` field to the data model:
|
||||
|
||||
```ts highlights={[["7"], ["8"]]}
|
||||
// other imports...
|
||||
import { Property } from "@mikro-orm/core"
|
||||
|
||||
class MySoftDeletable extends BaseEntity {
|
||||
// ...
|
||||
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Manage Soft-Deletable Models
|
||||
|
||||
Services extending the service factory have methods to soft delete and restore records for all models specified during its creation.
|
||||
|
||||
### Soft Delete a Record
|
||||
|
||||
For example, to soft delete a `MySoftDeletable` record:
|
||||
|
||||
```ts
|
||||
await helloModuleService.softDelete([
|
||||
"id_123", "id_321",
|
||||
])
|
||||
```
|
||||
|
||||
The method receives an array of IDs of records to delete.
|
||||
|
||||
### Retrieve Soft-Deleted Records
|
||||
|
||||
The `retrieve`, `list`, and `listAndCount` methods accept as a second parameter a configuration object.
|
||||
|
||||
To retrieve soft-deleted records, set `withDeleted` to `true` in the configuration object passed as a second parameter.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const deletedRecords = await helloModuleService
|
||||
.listMySoftDeletables({
|
||||
// ...
|
||||
}, {
|
||||
withDeleted: true,
|
||||
})
|
||||
```
|
||||
|
||||
### Restore a Soft-Deleted Record
|
||||
|
||||
To restore a `MySoftDeletable` record:
|
||||
|
||||
```ts
|
||||
await helloModuleService.restore([
|
||||
"id_123", "id_321",
|
||||
])
|
||||
```
|
||||
|
||||
The method also receives an array of IDs of records to restore.
|
||||
|
||||
If the data model isn't the main data model, its method names are `softDelete` and `restore` suffixed with the plural name of the model. For example, `softDeleteMySoftDeletable`.
|
||||
By default, all data models have a `deleted_at` property and are considered soft-deletable.
|
||||
|
||||
Reference in New Issue
Block a user