docs: improved data model docs (#11884)
* docs: improved data model docs * fix build errors
This commit is contained in:
@@ -56,7 +56,7 @@ You define the data model using the `define` method of the DML. It accepts two p
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Learn about other property types in [this chapter](../../../fundamentals/data-models/property-types/page.mdx).
|
||||
Learn about other property types in [this chapter](../../../fundamentals/data-models/properties/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Configure Data Model Properties`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to configure data model properties.
|
||||
|
||||
## Property’s Default Value
|
||||
|
||||
Use the `default` method on a property's definition 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/framework/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/framework/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 through a unique index.
|
||||
|
||||
For example:
|
||||
|
||||
export const uniqueHighlights = [
|
||||
["4", "unique", "Configure the `email` property to allow unique values only."]
|
||||
]
|
||||
|
||||
```ts highlights={uniqueHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const User = model.define("user", {
|
||||
email: model.text().unique(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default User
|
||||
```
|
||||
|
||||
In this example, multiple users can’t have the same email.
|
||||
@@ -1,13 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Data Model Default Properties`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you'll learn about the properties available by default in your data model.
|
||||
|
||||
When you create a data model, the following properties are created for you by Medusa:
|
||||
|
||||
- `created_at`: A `dateTime` property that stores when a record of the data model was created.
|
||||
- `updated_at`: A `dateTime` property that stores when a record of the data model was updated.
|
||||
- `deleted_at`: A `dateTime` property that stores when a record of the data model was deleted. When you soft-delete a record, Medusa sets the `deleted_at` property to the current date.
|
||||
@@ -6,35 +6,11 @@ export const metadata = {
|
||||
|
||||
In this chapter, you’ll learn how to define a database index on a data model.
|
||||
|
||||
## Define Database Index on Property
|
||||
<Note>
|
||||
|
||||
Use the `index` method on a property's definition to define a database index.
|
||||
You can also define an index on a property as explained in the [Properties chapter](../properties/page.mdx#define-database-index-on-property).
|
||||
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["5", "index", "Define an index on the `name` property."],
|
||||
["6", '"IDX_MY_CUSTOM_NAME"', "Index name is optional."]
|
||||
]
|
||||
|
||||
```ts highlights={highlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
id: model.id().primaryKey(),
|
||||
name: model.text().index(
|
||||
"IDX_MY_CUSTOM_NAME"
|
||||
),
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
The `index` method optionally accepts the name of the index as a parameter.
|
||||
|
||||
In this example, you define an index on the `name` property.
|
||||
|
||||
---
|
||||
</Note>
|
||||
|
||||
## Define Database Index on Data Model
|
||||
|
||||
@@ -73,7 +49,7 @@ An index can have conditions. For example:
|
||||
|
||||
export const conditionHighlights = [
|
||||
["10", "where", "Specify conditions on properties."],
|
||||
["11", "", "Create the index when `age` is `30`."]
|
||||
["11", "age", "Create the index when `age` is `30`."]
|
||||
]
|
||||
|
||||
```ts highlights={conditionHighlights}
|
||||
@@ -102,7 +78,7 @@ In the example above, the composite index is created on the `name` and `age` pro
|
||||
A property's condition can be a negation. For example:
|
||||
|
||||
export const negationHighlights = [
|
||||
["12", "", "Create the index when `age` is not `null`."]
|
||||
["12", "$ne", "Create the index when `age` is not `null`."]
|
||||
]
|
||||
|
||||
```ts highlights={negationHighlights}
|
||||
|
||||
@@ -8,7 +8,7 @@ In this chapter, you'll learn how to infer the type of a data model.
|
||||
|
||||
## How to Infer Type of Data Model?
|
||||
|
||||
Consider you have a `MyCustom` data model. You can't reference this data model in a type, such as a workflow input or service method output types, since it's a variable.
|
||||
Consider you have a `Post` data model. You can't reference this data model in a type, such as a workflow input or service method output types, since it's a variable.
|
||||
|
||||
Instead, Medusa provides `InferTypeOf` that transforms your data model to a type.
|
||||
|
||||
@@ -16,26 +16,26 @@ For example:
|
||||
|
||||
```ts
|
||||
import { InferTypeOf } from "@medusajs/framework/types"
|
||||
import { MyCustom } from "../models/my-custom" // relative path to the model
|
||||
import { Post } from "../modules/blog/models/post" // relative path to the model
|
||||
|
||||
export type MyCustom = InferTypeOf<typeof MyCustom>
|
||||
export type Post = InferTypeOf<typeof Post>
|
||||
```
|
||||
|
||||
`InferTypeOf` accepts as a type argument the type of the data model.
|
||||
|
||||
Since the `MyCustom` data model is a variable, use the `typeof` operator to pass the data model as a type argument to `InferTypeOf`.
|
||||
Since the `Post` data model is a variable, use the `typeof` operator to pass the data model as a type argument to `InferTypeOf`.
|
||||
|
||||
You can now use the `MyCustom` type to reference a data model in other types, such as in workflow inputs or service method outputs:
|
||||
You can now use the `Post` type to reference a data model in other types, such as in workflow inputs or service method outputs:
|
||||
|
||||
```ts title="Example Service"
|
||||
// other imports...
|
||||
import { InferTypeOf } from "@medusajs/framework/types"
|
||||
import { MyCustom } from "../models/my-custom"
|
||||
import { Post } from "../models/post"
|
||||
|
||||
type MyCustom = InferTypeOf<typeof MyCustom>
|
||||
type Post = InferTypeOf<typeof Post>
|
||||
|
||||
class HelloModuleService extends MedusaService({ MyCustom }) {
|
||||
async doSomething(): Promise<MyCustom> {
|
||||
class BlogModuleService extends MedusaService({ Post }) {
|
||||
async doSomething(): Promise<Post> {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,114 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Data Models Advanced Guides`,
|
||||
title: `${pageNumber} Data Models`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
Data models are created and managed in a module. To learn how to create a data model in a custom module, refer to the [Modules chapter](../modules/page.mdx).
|
||||
In this chapter, you'll learn what a data model is and how to create a data model.
|
||||
|
||||
In the next chapters, you'll learn about defining data models in more details. You'll learn about:
|
||||
## What is a Data Model?
|
||||
|
||||
- The different property types available.
|
||||
- How to set a property as a primary key.
|
||||
- How to create and manage relationships.
|
||||
- How to configure properties, such as making them nullable or searchable.
|
||||
- How to manually write migrations.
|
||||
A data model represents a table in the database. You create data models using Medusa's data modeling language (DML). It simplifies defining a table's columns, relations, and indexes with straightforward methods and configurations.
|
||||
|
||||
You create a data model in a [module](../modules/page.mdx). The module's service provides the methods to store and manage those data models. Then, you can resolve the module's service in other customizations, such as a [workflow](../workflows/page.mdx), to manage the data models' records.
|
||||
|
||||
---
|
||||
|
||||
## How to Create a Data Model
|
||||
|
||||
In a module, you can create a data model in a TypeScript or JavaScript file under the module's `models` directory.
|
||||
|
||||
So, for example, assuming you have a Blog Module at `src/modules/blog`, you can create a `Post` data model by creating the `src/modules/blog/models/post.ts` file with the following content:
|
||||
|
||||

|
||||
|
||||
```ts title="src/modules/blog/models/post.ts"
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
id: model.id().primaryKey(),
|
||||
title: model.text(),
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
You define the data model using the `define` method of the DML. It accepts two parameters:
|
||||
|
||||
1. The first one is the name of the data model's table in the database. Use snake-case names.
|
||||
2. The second is an object, which is the data model's schema. The schema's properties are defined using the `model`'s methods, such as `text` and `id`.
|
||||
- Data models automatically have the date properties `created_at`, `updated_at`, and `deleted_at`, so you don't need to add them manually.
|
||||
|
||||
The code snippet above defines a `Post` data model with `id` and `title` properties.
|
||||
|
||||
---
|
||||
|
||||
## Generate Migrations
|
||||
|
||||
After you create a data model in a module, then [register that module in your Medusa configurations](../modules/page.mdx#4-add-module-to-medusas-configurations), you must generate a migration to create the data model's table in the database.
|
||||
|
||||
A migration is a TypeScript or JavaScript file that defines database changes made by a module. Migrations are useful when you re-use a module or you're working in a team, so that when one member of a team makes a database change, everyone else can reflect it on their side by running the migrations.
|
||||
|
||||
For example, to generate a migration for the Blog Module, run the following command in your Medusa application's directory:
|
||||
|
||||
<Note>
|
||||
|
||||
If you're creating the module in a plugin, use the [plugin\:db\:generate command](!resources!/medusa-cli/commands/plugin#plugindbgenerate) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
```bash
|
||||
npx medusa db:generate blog
|
||||
```
|
||||
|
||||
The `db:generate` command of the Medusa CLI accepts one or more module names to generate the migration for. It will create a migration file for the Blog Module in the directory `src/modules/blog/migrations` similar to the following:
|
||||
|
||||
```ts
|
||||
import { Migration } from "@mikro-orm/migrations"
|
||||
|
||||
export class Migration20241121103722 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql("create table if not exists \"post\" (\"id\" text not null, \"title\" text not null, \"created_at\" timestamptz not null default now(), \"updated_at\" timestamptz not null default now(), \"deleted_at\" timestamptz null, constraint \"post_pkey\" primary key (\"id\"));")
|
||||
}
|
||||
|
||||
async down(): Promise<void> {
|
||||
this.addSql("drop table if exists \"post\" cascade;")
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
In the migration class, the `up` method creates the table `post` and defines its columns using PostgreSQL syntax. The `down` method drops the table.
|
||||
|
||||
### Run Migrations
|
||||
|
||||
To reflect the changes in the generated migration file on the database, run the `db:migrate` command:
|
||||
|
||||
<Note>
|
||||
|
||||
If you're creating the module in a plugin, run this command on the Medusa application that the plugin is installed in.
|
||||
|
||||
</Note>
|
||||
|
||||
```bash
|
||||
npx medusa db:migrate
|
||||
```
|
||||
|
||||
This creates the `post` table in the database.
|
||||
|
||||
### Migrations on Data Model Changes
|
||||
|
||||
Whenever you make a change to a data model, you must generate and run the migrations.
|
||||
|
||||
For example, if you add a new column to the `Post` data model, you must generate a new migration and run it.
|
||||
|
||||
---
|
||||
|
||||
## Manage Data Models
|
||||
|
||||
Your module's service should extend the [service factory](../modules/service-factory/page.mdx), which generates data-management methods for your module's data models.
|
||||
|
||||
For example, the Blog Module's service would have methods like `retrievePost` and `createPosts`.
|
||||
|
||||
Refer to the [Service Factory](../modules/service-factory/page.mdx) chapter to learn more about how to extend the service factory and manage data models, and refer to the [Service Factory Reference](!resources!/service-factory-reference) for the full list of generated methods and how to use them.
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
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.
|
||||
|
||||
## primaryKey Method
|
||||
|
||||
To set any `id`, `text`, or `number` property as a primary key, use the `primaryKey` method.
|
||||
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["4", "primaryKey", "Define the `id` property to be the data model's primary key."]
|
||||
]
|
||||
|
||||
```ts highlights={highlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
id: model.id().primaryKey(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
In the example above, the `id` property is defined as the data model's primary key.
|
||||
@@ -0,0 +1,412 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Data Model Properties`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you'll learn about the different property types you can use in a data model and how to configure a data model's properties.
|
||||
|
||||
## Data Model's Default Properties
|
||||
|
||||
By default, Medusa creates the following properties for every data model:
|
||||
|
||||
- `created_at`: A [dateTime](#dateTime) property that stores when a record of the data model was created.
|
||||
- `updated_at`: A [dateTime](#dateTime) property that stores when a record of the data model was updated.
|
||||
- `deleted_at`: A [dateTime](#dateTime) property that stores when a record of the data model was deleted. When you soft-delete a record, Medusa sets the `deleted_at` property to the current date.
|
||||
|
||||
---
|
||||
|
||||
## Property Types
|
||||
|
||||
This section covers the different property types you can define in a data model's schema using the `model` methods.
|
||||
|
||||
### id
|
||||
|
||||
The `id` method defines an automatically generated string ID property. The generated ID is a unique string that has a mix of letters and numbers.
|
||||
|
||||
For example:
|
||||
|
||||
export const idHighlights = [["4", ".id()", "Define an `id` property."]]
|
||||
|
||||
```ts highlights={idHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
id: model.id(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### 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/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
name: model.text(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### 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/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
age: model.number(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### float
|
||||
|
||||
<Note>
|
||||
|
||||
This property is only available after [Medusa v2.1.2](https://github.com/medusajs/medusa/releases/tag/v2.1.2).
|
||||
|
||||
</Note>
|
||||
|
||||
The `float` method defines a number property that allows for values with decimal places.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Use this property type when it's less important to have high precision for numbers with large decimal places. Alternatively, for higher percision, use the [bigNumber property](#bignumber).
|
||||
|
||||
</Note>
|
||||
|
||||
For example:
|
||||
|
||||
export const floatHighlights = [["4", "float", "Define a `float` property."]]
|
||||
|
||||
```ts highlights={floatHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
rating: model.float(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### bigNumber
|
||||
|
||||
The `bigNumber` method defines a number property that expects large numbers, such as prices.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Use this property type when it's important to have high precision for numbers with large decimal places. Alternatively, for less percision, use the [float property](#float).
|
||||
|
||||
</Note>
|
||||
|
||||
For example:
|
||||
|
||||
export const bigNumberHighlights = [["4", "bigNumber", "Define a `bigNumber` property."]]
|
||||
|
||||
```ts highlights={bigNumberHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
price: model.bigNumber(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### 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/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
hasAccount: model.boolean(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### 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/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
color: model.enum(["black", "white"]),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
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/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
date_of_birth: model.dateTime(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### 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/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
metadata: model.json(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### array
|
||||
|
||||
The `array` method defines an array of strings property.
|
||||
|
||||
For example:
|
||||
|
||||
export const arrHightlights = [["4", "array", "Define an `array` property."]]
|
||||
|
||||
```ts highlights={arrHightlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
names: model.array(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
### Properties Reference
|
||||
|
||||
Refer to the [Data Model Language (DML) reference](!resources!/references/data-model) for a full reference of the properties.
|
||||
|
||||
---
|
||||
|
||||
## Set Primary Key Property
|
||||
|
||||
To set any `id`, `text`, or `number` property as a primary key, use the `primaryKey` method.
|
||||
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["4", "primaryKey", "Define the `id` property to be the data model's primary key."]
|
||||
]
|
||||
|
||||
```ts highlights={highlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
id: model.id().primaryKey(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
In the example above, the `id` property is defined as the data model's primary key.
|
||||
|
||||
---
|
||||
|
||||
## Property Default Value
|
||||
|
||||
Use the `default` method on a property's definition 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/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
color: model
|
||||
.enum(["black", "white"])
|
||||
.default("black"),
|
||||
age: model
|
||||
.number()
|
||||
.default(0),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
In this example, you set the default value of the `color` enum property to `black`, and that of the `age` number property to `0`.
|
||||
|
||||
---
|
||||
|
||||
## Make Property Optional
|
||||
|
||||
Use the `nullable` method to indicate that a property’s value can be `null`. This is useful when you want a property to be optional.
|
||||
|
||||
For example:
|
||||
|
||||
export const nullableHighlights = [
|
||||
["4", "nullable", "Configure the `price` property to allow `null` values."]
|
||||
]
|
||||
|
||||
```ts highlights={nullableHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
price: model.bigNumber().nullable(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
In the example above, the `price` property is configured to allow `null` values, making it optional.
|
||||
|
||||
---
|
||||
|
||||
## Unique Property
|
||||
|
||||
The `unique` method indicates that a property’s value must be unique in the database through a unique index.
|
||||
|
||||
For example:
|
||||
|
||||
export const uniqueHighlights = [
|
||||
["4", "unique", "Configure the `email` property to allow unique values only."]
|
||||
]
|
||||
|
||||
```ts highlights={uniqueHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const User = model.define("user", {
|
||||
email: model.text().unique(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default User
|
||||
```
|
||||
|
||||
In this example, multiple users can’t have the same email.
|
||||
|
||||
---
|
||||
|
||||
## Define Database Index on Property
|
||||
|
||||
Use the `index` method on a property's definition to define a database index.
|
||||
|
||||
For example:
|
||||
|
||||
export const dbIndexHighlights = [
|
||||
["5", "index", "Define an index on the `name` property."],
|
||||
["6", '"IDX_MY_CUSTOM_NAME"', "Index name is optional."]
|
||||
]
|
||||
|
||||
```ts highlights={dbIndexHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
id: model.id().primaryKey(),
|
||||
name: model.text().index(
|
||||
"IDX_MY_CUSTOM_NAME"
|
||||
),
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
The `index` method optionally accepts the name of the index as a parameter.
|
||||
|
||||
In this example, you define an index on the `name` property.
|
||||
|
||||
---
|
||||
|
||||
## Define 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 data model's searchable properties are queried to find matching records.
|
||||
|
||||
Use the `searchable` method on a `text` property to indicate that it's searchable.
|
||||
|
||||
For example:
|
||||
|
||||
export const searchableHighlights = [
|
||||
["4", "searchable", "Define the `title` property as searchable."]
|
||||
]
|
||||
|
||||
```ts highlights={searchableHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
title: model.text().searchable(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default Post
|
||||
```
|
||||
|
||||
In this example, the `title` property is searchable.
|
||||
|
||||
### Search Example
|
||||
|
||||
If you pass a `q` filter to the `listPosts` method:
|
||||
|
||||
```ts
|
||||
const posts = await blogModuleService.listPosts({
|
||||
q: "New Products",
|
||||
})
|
||||
```
|
||||
|
||||
This retrieves records that include `New Products` in their `title` property.
|
||||
@@ -1,241 +0,0 @@
|
||||
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. The generated ID is a unique string that has a mix of letters and numbers.
|
||||
|
||||
For example:
|
||||
|
||||
export const idHighlights = [["4", ".id()", "Define an `id` property."]]
|
||||
|
||||
```ts highlights={idHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
id: model.id(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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/framework/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/framework/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
age: model.number(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## float
|
||||
|
||||
<Note>
|
||||
|
||||
This property is only available after [Medusa v2.1.2](https://github.com/medusajs/medusa/releases/tag/v2.1.2).
|
||||
|
||||
</Note>
|
||||
|
||||
The `float` method defines a number property that allows for values with decimal places.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Use this property type when it's less important to have high precision for numbers with large decimal places. Alternatively, for higher percision, use the [bigNumber property](#bignumber).
|
||||
|
||||
</Note>
|
||||
|
||||
For example:
|
||||
|
||||
export const floatHighlights = [["4", "float", "Define a `float` property."]]
|
||||
|
||||
```ts highlights={floatHighlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
rating: model.float(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## bigNumber
|
||||
|
||||
The `bigNumber` method defines a number property that expects large numbers, such as prices.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Use this property type when it's important to have high precision for numbers with large decimal places. Alternatively, for less percision, use the [float property](#float).
|
||||
|
||||
</Note>
|
||||
|
||||
For example:
|
||||
|
||||
export const bigNumberHighlights = [["4", "bigNumber", "Define a `bigNumber` property."]]
|
||||
|
||||
```ts highlights={bigNumberHighlights}
|
||||
import { model } from "@medusajs/framework/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/framework/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/framework/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/framework/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/framework/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
metadata: model.json(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## array
|
||||
|
||||
The `array` method defines an array of strings property.
|
||||
|
||||
For example:
|
||||
|
||||
export const arrHightlights = [["4", "array", "Define an `array` property."]]
|
||||
|
||||
```ts highlights={arrHightlights}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const MyCustom = model.define("my_custom", {
|
||||
names: model.array(),
|
||||
// ...
|
||||
})
|
||||
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Properties Reference
|
||||
|
||||
Refer to the [Data Model API reference](!resources!/references/data-model) for a full reference of the properties.
|
||||
@@ -67,7 +67,7 @@ The `belongsTo` method also requires passing as a second parameter an object wit
|
||||
|
||||
### Optional Relationship
|
||||
|
||||
To make the relationship optional on the `hasOne` or `belongsTo` side, use the `nullable` method on either property as explained in [this chapter](../configure-properties/page.mdx#nullable-property).
|
||||
To make the relationship optional on the `hasOne` or `belongsTo` side, use the `nullable` method on either property as explained in [this chapter](../properties/page.mdx#make-property-optional).
|
||||
|
||||
### One-sided One-to-One Relationship
|
||||
|
||||
@@ -142,7 +142,7 @@ In this example, a store has many products, but a product belongs to one store.
|
||||
|
||||
### Optional Relationship
|
||||
|
||||
To make the relationship optional on the `belongsTo` side, use the `nullable` method on the property as explained in [this chapter](../configure-properties/page.mdx#nullable-property).
|
||||
To make the relationship optional on the `belongsTo` side, use the `nullable` method on the property as explained in [this chapter](../properties/page.mdx#make-property-optional).
|
||||
|
||||
### One-to-Many Relationship in the Database
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
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 data model's searchable properties are queried to find matching records.
|
||||
|
||||
---
|
||||
|
||||
## Define a Searchable Property
|
||||
|
||||
Use the `searchable` method on a `text` property to indicate that it's searchable.
|
||||
|
||||
For example:
|
||||
|
||||
export const searchableHighlights = [
|
||||
["4", "searchable", "Define the `name` property as searchable."]
|
||||
]
|
||||
|
||||
```ts highlights={searchableHighlights}
|
||||
import { model } from "@medusajs/framework/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",
|
||||
})
|
||||
```
|
||||
|
||||
This retrieves records that include `John` in their `name` property.
|
||||
@@ -1,32 +1,46 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Write Migration`,
|
||||
title: `${pageNumber} Migrations`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you'll learn how to create a migration and write it manually.
|
||||
In this chapter, you'll learn what a migration is and how to generate a migration or write it manually.
|
||||
|
||||
## What is a Migration?
|
||||
|
||||
A migration is a class created in a TypeScript or JavaScript file under a module's `migrations` directory. It has two methods:
|
||||
A migration is a TypeScript or JavaScript file that defines database changes made by a module. Migrations are useful when you re-use a module or you're working in a team, so that when one member of a team makes a database change, everyone else can reflect it on their side by running the migrations.
|
||||
|
||||
The migration's file has a class with two methods:
|
||||
|
||||
- The `up` method reflects changes on the database.
|
||||
- The `down` method reverts the changes made in the `up` method.
|
||||
|
||||
---
|
||||
|
||||
## How to Write a Migration?
|
||||
## Generate Migration
|
||||
|
||||
The Medusa CLI tool provides a [db:generate](!resources!/medusa-cli/commands/db#dbgenerate) command to generate a migration for the specified modules' data models.
|
||||
Instead of you writing the migration manually, the Medusa CLI tool provides a [db:generate](!resources!/medusa-cli/commands/db#dbgenerate) command to generate a migration for a modules' data models.
|
||||
|
||||
Alternatively, you can manually create a migration file under the `migrations` directory of your module.
|
||||
For example, assuming you have a `blog` Module, you can generate a migration for it by running the following command:
|
||||
|
||||
```bash
|
||||
npx medusa db:generate blog
|
||||
```
|
||||
|
||||
This generates a migration file under the `migrations` directory of the Blog Module. You can then run it to reflect the changes in the database as mentioned in [this section](#run-the-migration).
|
||||
|
||||
---
|
||||
|
||||
## Write a Migration Manually
|
||||
|
||||
You can also write migrations manually. To do that, create a file in the `migrations` directory of the module and in it, a class that has an `up` and `down` method. The class's name should be of the format `Migration{YEAR}{MONTH}{DAY}{HOUR}{MINUTE}.ts` to ensure migrations are ran in the correct order.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="src/modules/blog/migrations/Migration20240429.ts"
|
||||
import { Migration } from "@mikro-orm/migrations"
|
||||
|
||||
export class Migration20240702105919 extends Migration {
|
||||
export class Migration202507021059 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql("create table if not exists \"author\" (\"id\" text not null, \"name\" text not null, \"created_at\" timestamptz not null default now(), \"updated_at\" timestamptz not null default now(), \"deleted_at\" timestamptz null, constraint \"author_pkey\" primary key (\"id\"));")
|
||||
@@ -39,9 +53,7 @@ export class Migration20240702105919 extends Migration {
|
||||
}
|
||||
```
|
||||
|
||||
The migration's file name should be of the format `Migration{YEAR}{MONTH}{DAY}.ts`. The migration class in the file extends the `Migration` class imported from `@mikro-orm/migrations`.
|
||||
|
||||
In the `up` and `down` method of the migration class, you use the `addSql` method provided by MikroORM's `Migration` class to run PostgreSQL syntax.
|
||||
The migration class in the file extends the `Migration` class imported from `@mikro-orm/migrations`. In the `up` and `down` method of the migration class, you use the `addSql` method provided by MikroORM's `Migration` class to run PostgreSQL syntax.
|
||||
|
||||
In the example above, the `up` method creates the table `author`, and the `down` method drops the table if the migration is reverted.
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ You define the data model using the `define` method of the DML. It accepts two p
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Learn about other property types in [this chapter](../../fundamentals/data-models/property-types/page.mdx).
|
||||
Learn about other property types in [this chapter](../../fundamentals/data-models/properties/page.mdx#property-types).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ For example:
|
||||
export const failureStatusHighlights = [
|
||||
["17", "transactionId", "Receive the workflow execution's transaction ID as an input to the step."],
|
||||
["20", "resolve", "Resolve the workflow engine's main service."],
|
||||
["24", "setStepSuccess", "Change the step's status to successful."],
|
||||
["24", "setStepFailure", "Change the step's status to failed."],
|
||||
["28", "stepId", "The ID of the step as passed to `createStep`'s first parameter when it was created."],
|
||||
["29", "workflowId", "The ID of the workflow as passed to `createWorkflow`'s first parameter when it was created."],
|
||||
["31", "stepResponse", "The response returned by the step, since an `async` step can't return a response in its definition."]
|
||||
@@ -291,8 +291,9 @@ To retrieve the workflow execution's details at a later point, you must enable [
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["18", "resolve", "Resolve the workflow engine from the Medusa container."],
|
||||
["30", "subscribe", "Subscribe to status changes of the workflow execution."],
|
||||
["11", "resolve", "Resolve the workflow engine from the Medusa container."],
|
||||
["23", "subscribe", "Subscribe to status changes of the workflow execution."],
|
||||
["29", "unsubscribe", "Unsubscribe once you have the result"]
|
||||
]
|
||||
|
||||
```ts title="src/api/workflows/route.ts" highlights={highlights} collapsibleLines="1-11" expandButtonLabel="Show Imports"
|
||||
|
||||
@@ -22,29 +22,26 @@ export const generatedEditDates = {
|
||||
"app/learn/fundamentals/workflows/execute-another-workflow/page.mdx": "2024-12-09T15:56:22.895Z",
|
||||
"app/learn/fundamentals/modules/loaders/page.mdx": "2024-12-09T10:32:29.221Z",
|
||||
"app/learn/fundamentals/admin/widgets/page.mdx": "2024-12-09T16:43:24.260Z",
|
||||
"app/learn/fundamentals/data-models/page.mdx": "2024-12-09T11:34:51.065Z",
|
||||
"app/learn/fundamentals/data-models/page.mdx": "2025-03-18T07:55:56.252Z",
|
||||
"app/learn/fundamentals/modules/remote-link/page.mdx": "2024-09-30T08:43:53.127Z",
|
||||
"app/learn/fundamentals/api-routes/protected-routes/page.mdx": "2025-03-17T11:47:10.101Z",
|
||||
"app/learn/fundamentals/workflows/add-workflow-hook/page.mdx": "2024-12-09T14:42:39.693Z",
|
||||
"app/learn/fundamentals/events-and-subscribers/data-payload/page.mdx": "2024-10-21T13:30:21.369Z",
|
||||
"app/learn/fundamentals/data-models/default-properties/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/workflows/advanced-example/page.mdx": "2024-09-11T10:46:59.975Z",
|
||||
"app/learn/fundamentals/events-and-subscribers/emit-event/page.mdx": "2024-11-25T16:19:32.168Z",
|
||||
"app/learn/fundamentals/workflows/conditions/page.mdx": "2025-01-27T08:45:19.027Z",
|
||||
"app/learn/fundamentals/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00",
|
||||
"app/learn/fundamentals/admin/page.mdx": "2024-10-23T07:08:55.898Z",
|
||||
"app/learn/fundamentals/workflows/long-running-workflow/page.mdx": "2025-01-27T08:45:19.028Z",
|
||||
"app/learn/fundamentals/workflows/long-running-workflow/page.mdx": "2025-03-18T08:02:14.085Z",
|
||||
"app/learn/fundamentals/workflows/constructor-constraints/page.mdx": "2025-02-12T13:55:33.437Z",
|
||||
"app/learn/fundamentals/data-models/write-migration/page.mdx": "2025-03-11T12:58:05.655Z",
|
||||
"app/learn/fundamentals/data-models/write-migration/page.mdx": "2025-03-18T08:00:44.980Z",
|
||||
"app/learn/fundamentals/data-models/manage-relationships/page.mdx": "2025-02-11T15:53:12.541Z",
|
||||
"app/learn/fundamentals/modules/remote-query/page.mdx": "2024-07-21T21:20:24+02:00",
|
||||
"app/learn/fundamentals/modules/options/page.mdx": "2025-02-12T16:00:28.484Z",
|
||||
"app/learn/fundamentals/data-models/relationships/page.mdx": "2025-02-03T08:01:18.094Z",
|
||||
"app/learn/fundamentals/data-models/relationships/page.mdx": "2025-03-18T07:52:07.421Z",
|
||||
"app/learn/fundamentals/workflows/compensation-function/page.mdx": "2024-12-06T14:34:50.384Z",
|
||||
"app/learn/fundamentals/modules/service-factory/page.mdx": "2024-10-21T13:30:21.371Z",
|
||||
"app/learn/fundamentals/data-models/primary-key/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/modules/module-links/page.mdx": "2024-09-30T08:43:53.126Z",
|
||||
"app/learn/fundamentals/data-models/searchable-property/page.mdx": "2024-10-21T13:30:21.369Z",
|
||||
"app/learn/fundamentals/scheduled-jobs/execution-number/page.mdx": "2024-10-21T13:30:21.371Z",
|
||||
"app/learn/fundamentals/api-routes/parameters/page.mdx": "2025-02-14T08:34:03.184Z",
|
||||
"app/learn/fundamentals/api-routes/http-methods/page.mdx": "2024-10-21T13:30:21.367Z",
|
||||
@@ -53,10 +50,8 @@ export const generatedEditDates = {
|
||||
"app/learn/fundamentals/admin/ui-routes/page.mdx": "2025-02-24T09:35:11.752Z",
|
||||
"app/learn/fundamentals/api-routes/middlewares/page.mdx": "2025-03-04T10:16:15.029Z",
|
||||
"app/learn/fundamentals/modules/isolation/page.mdx": "2024-12-09T11:02:38.087Z",
|
||||
"app/learn/fundamentals/data-models/configure-properties/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/data-models/index/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/data-models/index/page.mdx": "2025-03-18T07:59:07.798Z",
|
||||
"app/learn/fundamentals/custom-cli-scripts/page.mdx": "2024-10-23T07:08:55.898Z",
|
||||
"app/learn/fundamentals/data-models/property-types/page.mdx": "2024-12-12T10:41:32.999Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2025-02-13T16:39:29.636Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/integration-tests/page.mdx": "2024-12-09T15:52:01.019Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2025-02-11T15:56:03.835Z",
|
||||
@@ -76,12 +71,12 @@ export const generatedEditDates = {
|
||||
"app/learn/fundamentals/module-links/query/page.mdx": "2025-03-11T15:35:10.605Z",
|
||||
"app/learn/fundamentals/modules/db-operations/page.mdx": "2024-12-09T14:40:50.581Z",
|
||||
"app/learn/fundamentals/modules/multiple-services/page.mdx": "2024-10-21T13:30:21.370Z",
|
||||
"app/learn/fundamentals/modules/page.mdx": "2025-03-11T13:00:37.391Z",
|
||||
"app/learn/fundamentals/modules/page.mdx": "2025-03-18T07:51:09.049Z",
|
||||
"app/learn/debugging-and-testing/instrumentation/page.mdx": "2025-02-24T08:12:53.132Z",
|
||||
"app/learn/fundamentals/api-routes/additional-data/page.mdx": "2025-01-27T08:45:19.025Z",
|
||||
"app/learn/fundamentals/workflows/variable-manipulation/page.mdx": "2025-01-27T08:45:19.029Z",
|
||||
"app/learn/customization/custom-features/api-route/page.mdx": "2024-12-09T10:39:30.046Z",
|
||||
"app/learn/customization/custom-features/module/page.mdx": "2024-12-09T14:36:02.100Z",
|
||||
"app/learn/customization/custom-features/module/page.mdx": "2025-03-18T07:49:30.590Z",
|
||||
"app/learn/customization/custom-features/workflow/page.mdx": "2024-12-09T14:36:29.482Z",
|
||||
"app/learn/customization/extend-features/extend-create-product/page.mdx": "2025-01-06T11:18:58.250Z",
|
||||
"app/learn/customization/custom-features/page.mdx": "2024-12-09T10:46:28.593Z",
|
||||
@@ -98,7 +93,7 @@ export const generatedEditDates = {
|
||||
"app/learn/customization/next-steps/page.mdx": "2024-12-06T14:34:53.356Z",
|
||||
"app/learn/fundamentals/modules/architectural-modules/page.mdx": "2024-10-21T13:30:21.367Z",
|
||||
"app/learn/introduction/architecture/page.mdx": "2025-03-12T14:39:09.724Z",
|
||||
"app/learn/fundamentals/data-models/infer-type/page.mdx": "2024-12-09T15:54:08.713Z",
|
||||
"app/learn/fundamentals/data-models/infer-type/page.mdx": "2025-03-18T07:41:01.936Z",
|
||||
"app/learn/fundamentals/custom-cli-scripts/seed-data/page.mdx": "2024-12-09T14:38:06.385Z",
|
||||
"app/learn/fundamentals/environment-variables/page.mdx": "2025-03-11T08:55:03.343Z",
|
||||
"app/learn/build/page.mdx": "2024-12-09T11:05:17.383Z",
|
||||
@@ -122,5 +117,6 @@ export const generatedEditDates = {
|
||||
"app/learn/configurations/medusa-config/page.mdx": "2025-03-11T14:27:04.528Z",
|
||||
"app/learn/configurations/ts-aliases/page.mdx": "2025-02-11T16:57:46.683Z",
|
||||
"app/learn/production/worker-mode/page.mdx": "2025-03-11T15:21:50.906Z",
|
||||
"app/learn/fundamentals/module-links/read-only/page.mdx": "2025-03-17T14:18:29.924Z"
|
||||
"app/learn/fundamentals/module-links/read-only/page.mdx": "2025-03-17T14:18:29.924Z",
|
||||
"app/learn/fundamentals/data-models/properties/page.mdx": "2025-03-18T07:57:17.826Z"
|
||||
}
|
||||
@@ -456,42 +456,12 @@ export const generatedSidebars = [
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/learn/fundamentals/data-models/property-types",
|
||||
"title": "Property Types",
|
||||
"path": "/learn/fundamentals/data-models/properties",
|
||||
"title": "Properties",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.2. Property Types",
|
||||
"chapterTitle": "3.4.2. Properties",
|
||||
"number": "3.4.2."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/learn/fundamentals/data-models/primary-key",
|
||||
"title": "Primary Key",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.3. Primary Key",
|
||||
"number": "3.4.3."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/learn/fundamentals/data-models/default-properties",
|
||||
"title": "Default Properties",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.4. Default Properties",
|
||||
"number": "3.4.4."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/learn/fundamentals/data-models/configure-properties",
|
||||
"title": "Configure Properties",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.5. Configure Properties",
|
||||
"number": "3.4.5."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -499,8 +469,8 @@ export const generatedSidebars = [
|
||||
"path": "/learn/fundamentals/data-models/relationships",
|
||||
"title": "Relationships",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.6. Relationships",
|
||||
"number": "3.4.6."
|
||||
"chapterTitle": "3.4.3. Relationships",
|
||||
"number": "3.4.3."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
@@ -509,8 +479,8 @@ export const generatedSidebars = [
|
||||
"path": "/learn/fundamentals/data-models/manage-relationships",
|
||||
"title": "Manage Relationships",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.7. Manage Relationships",
|
||||
"number": "3.4.7."
|
||||
"chapterTitle": "3.4.4. Manage Relationships",
|
||||
"number": "3.4.4."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
@@ -519,8 +489,8 @@ export const generatedSidebars = [
|
||||
"path": "/learn/fundamentals/data-models/index",
|
||||
"title": "Define Index",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.8. Define Index",
|
||||
"number": "3.4.8."
|
||||
"chapterTitle": "3.4.5. Define Index",
|
||||
"number": "3.4.5."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
@@ -529,28 +499,18 @@ export const generatedSidebars = [
|
||||
"path": "/learn/fundamentals/data-models/check-constraints",
|
||||
"title": "Check Constraints",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.9. Check Constraints",
|
||||
"number": "3.4.9."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/learn/fundamentals/data-models/searchable-property",
|
||||
"title": "Searchable Property",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.10. Searchable Property",
|
||||
"number": "3.4.10."
|
||||
"chapterTitle": "3.4.6. Check Constraints",
|
||||
"number": "3.4.6."
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/learn/fundamentals/data-models/write-migration",
|
||||
"title": "Write Migration",
|
||||
"title": "Migrations",
|
||||
"children": [],
|
||||
"chapterTitle": "3.4.11. Write Migration",
|
||||
"number": "3.4.11."
|
||||
"chapterTitle": "3.4.7. Migrations",
|
||||
"number": "3.4.7."
|
||||
}
|
||||
],
|
||||
"chapterTitle": "3.4. Data Models",
|
||||
|
||||
+10016
-9939
File diff suppressed because it is too large
Load Diff
@@ -244,23 +244,8 @@ export const sidebars = [
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/fundamentals/data-models/property-types",
|
||||
title: "Property Types",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/fundamentals/data-models/primary-key",
|
||||
title: "Primary Key",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/fundamentals/data-models/default-properties",
|
||||
title: "Default Properties",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/fundamentals/data-models/configure-properties",
|
||||
title: "Configure Properties",
|
||||
path: "/learn/fundamentals/data-models/properties",
|
||||
title: "Properties",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
@@ -282,15 +267,10 @@ export const sidebars = [
|
||||
path: "/learn/fundamentals/data-models/check-constraints",
|
||||
title: "Check Constraints",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/fundamentals/data-models/searchable-property",
|
||||
title: "Searchable Property",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/fundamentals/data-models/write-migration",
|
||||
title: "Write Migration",
|
||||
title: "Migrations",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -128,6 +128,31 @@ const redirects = async () => {
|
||||
destination: "/learn/configurations/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/learn/fundamentals/data-models/configure-properties",
|
||||
destination: "/learn/fundamentals/data-models/properties",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/learn/fundamentals/data-models/default-properties",
|
||||
destination: "/learn/fundamentals/data-models/properties",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/learn/fundamentals/data-models/primary-key",
|
||||
destination: "/learn/fundamentals/data-models/properties",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/learn/fundamentals/data-models/property-types",
|
||||
destination: "/learn/fundamentals/data-models/properties",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/learn/fundamentals/data-models/searchable-property",
|
||||
destination: "/learn/fundamentals/data-models/properties",
|
||||
permanent: true,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -1063,7 +1063,7 @@ const MyCustom = model.define("my_custom", {
|
||||
})
|
||||
```
|
||||
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/property-types).
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/properties).
|
||||
|
||||
### Set Primary Key
|
||||
|
||||
@@ -1106,7 +1106,7 @@ const MyCustom = model.define("my_custom", {
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/primary-key).
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/properties#set-primary-key-property).
|
||||
|
||||
### Default Property Value
|
||||
|
||||
@@ -1128,7 +1128,7 @@ const MyCustom = model.define("my_custom", {
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/configure-properties).
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/properties#property-default-value).
|
||||
|
||||
### Nullable Property
|
||||
|
||||
@@ -1145,7 +1145,7 @@ const MyCustom = model.define("my_custom", {
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/configure-properties#nullable-property).
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/properties#make-property-optional).
|
||||
|
||||
### Unique Property
|
||||
|
||||
@@ -1162,7 +1162,7 @@ const User = model.define("user", {
|
||||
export default User
|
||||
```
|
||||
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/configure-properties#unique-property).
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/properties#unique-property).
|
||||
|
||||
### Define Database Index on Property
|
||||
|
||||
@@ -1181,7 +1181,7 @@ const MyCustom = model.define("my_custom", {
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/index#define-database-index-on-property).
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/properties#define-database-index-on-property).
|
||||
|
||||
### Define Composite Index on Data Model
|
||||
|
||||
@@ -1208,7 +1208,7 @@ const MyCustom = model.define("my_custom", {
|
||||
export default MyCustom
|
||||
```
|
||||
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/index#define-database-index-on-data-model).
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/index).
|
||||
|
||||
### Make a Property Searchable
|
||||
|
||||
@@ -1239,7 +1239,7 @@ const myCustoms = await helloModuleService.listMyCustoms({
|
||||
})
|
||||
```
|
||||
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/searchable-property).
|
||||
Learn more in [this documentation](!docs!/learn/fundamentals/data-models/properties#searchable-property).
|
||||
|
||||
### Create One-to-One Relationship
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ The `Wishlist` model has the following properties:
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about data model [properties](!docs!/learn/fundamentals/data-models/property-types) and [relations](!docs!/learn/fundamentals/data-models/relationships).
|
||||
Learn more about data model [properties](!docs!/learn/fundamentals/data-models/properties) and [relations](!docs!/learn/fundamentals/data-models/relationships).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ In the data model, you define the following properties:
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about data model [properties](!docs!/learn/fundamentals/data-models/property-types) and [relations](!docs!/learn/fundamentals/data-models/relationships).
|
||||
Learn more about data model [properties](!docs!/learn/fundamentals/data-models/properties) and [relations](!docs!/learn/fundamentals/data-models/relationships).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ You define the following properties for the `Vendor` data model:
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about data model [properties](!docs!/learn/fundamentals/data-models/property-types) and [relations](!docs!/learn/fundamentals/data-models/relationships).
|
||||
Learn more about data model [properties](!docs!/learn/fundamentals/data-models/properties) and [relations](!docs!/learn/fundamentals/data-models/relationships).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user