From b41a4ceea87f6250ff5db50a5947f2a1d9bf5754 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 4 Dec 2024 20:04:36 +0200 Subject: [PATCH 1/2] docs: add documentation for check constraints (#10425) --- .../data-models/check-constraints/page.mdx | 86 +++++++++++++++++++ www/apps/book/generated/edit-dates.mjs | 3 +- www/apps/book/sidebar.mjs | 5 ++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 www/apps/book/app/learn/advanced-development/data-models/check-constraints/page.mdx diff --git a/www/apps/book/app/learn/advanced-development/data-models/check-constraints/page.mdx b/www/apps/book/app/learn/advanced-development/data-models/check-constraints/page.mdx new file mode 100644 index 0000000000000..59c11996e6349 --- /dev/null +++ b/www/apps/book/app/learn/advanced-development/data-models/check-constraints/page.mdx @@ -0,0 +1,86 @@ +export const metadata = { + title: `${pageNumber} Add Data Model Check Constraints`, +} + +# {metadata.title} + +In this chapter, you'll learn how to add check constraints to your data model. + +## What is a Check Constraint? + +A check constraint is a condition that must be satisfied by records inserted into a database table, otherwise an error is thrown. + +For example, if you have a data model with a `price` property, you want to only allow positive number values. So, you add a check constraint that fails when inserting a record with a negative price value. + +--- + +## How to Set a Check Constraint? + +To set check constraints on a data model, use the `checks` method. This method accepts an array of check constraints to apply on the data model. + +For example, to set a check constraint on a `price` property that ensures its value can only be a positive number: + +export const checks1Highlights = [ + ["7", "checks", "Add check constraints to the data model."], + ["8", "columns", "An object of column names for each property."], + ["8", "`${columns.price} >= 0`", "Return a SQL check constraint expression."] +] + +```ts highlights={checks1Highlights} +import { model } from "@medusajs/framework/utils" + +const CustomProduct = model.define('custom_product', { + // ... + price: model.bigNumber(), +}) +.checks([ + (columns) => `${columns.price} >= 0` +]) +``` + +The item passed in the array parameter of `checks` can be a callback function that accepts as a parameter an object whose keys are the names of the properties in the data model schema, and values the respective column name in the database. + +The function returns a string indicating the [SQL check constraint expression](https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS). In the expression, use the `columns` parameter to access a property's column name. + +You can also pass an object to the `checks` method: + +export const checks2Highlights = [ + ["7", "checks", "Add check constraints to the data model."], + ["9", "name", "The check constraint's name."], + ["10", "expression", "A function that returns the SQL check constraint expression."] +] + +```ts highlights={checks2Highlights} +import { model } from "@medusajs/framework/utils" + +const CustomProduct = model.define('custom_product', { + // ... + price: model.bigNumber(), +}) +.checks([ + { + name: 'custom_product_price_check', + expression: (columns) => `${columns.price} >= 0` + } +]) +``` + +The object accepts the following properties: + +- `name`: The check constraint's name. +- `expression`: A function similar to the one that can be passed to the array. It accepts an object of columns and returns an [SQL check constraint expression](https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS). + +--- + +## Apply in Migrations + +After adding the check constraint, make sure to generate and run migrations if you already have the table in the database. Otherwise, the check constraint won't be reflected. + +To generate a migration for the data model's module then reflect it on the database, run the following command: + +```bash +npx medusa db:generate custom_module +npx medusa db:migrate +``` + +The first command generates the migration under the `migrations` directory of your module's directory, and the second reflects it on the database. diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 5b7278e034846..55efbb544b2d0 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -117,5 +117,6 @@ export const generatedEditDates = { "app/learn/build/page.mdx": "2024-11-11T11:08:41.832Z", "app/learn/deployment/general/page.mdx": "2024-11-25T14:33:50.439Z", "app/learn/advanced-development/workflows/multiple-step-usage/page.mdx": "2024-11-12T11:11:49.191Z", - "app/learn/installation/page.mdx": "2024-11-28T14:18:21.905Z" + "app/learn/installation/page.mdx": "2024-11-28T14:18:21.905Z", + "app/learn/advanced-development/data-models/check-constraints/page.mdx": "2024-12-04T10:39:01.764Z" } \ No newline at end of file diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs index a29c94145e650..18049baae31f4 100644 --- a/www/apps/book/sidebar.mjs +++ b/www/apps/book/sidebar.mjs @@ -370,6 +370,11 @@ export const sidebar = numberSidebarItems( path: "/learn/advanced-development/data-models/index", title: "Define Index", }, + { + type: "link", + path: "/learn/advanced-development/data-models/check-constraints", + title: "Check Constraints", + }, { type: "link", path: "/learn/advanced-development/data-models/searchable-property", From 644f1fbbaf7f7c37ed1dcea72b7d048d23ad6da1 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Wed, 4 Dec 2024 20:04:57 +0200 Subject: [PATCH 2/2] docs: add note about default owner table in many-to-many (#10426) --- .../advanced-development/data-models/relationships/page.mdx | 6 ++++++ www/apps/book/generated/edit-dates.mjs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/www/apps/book/app/learn/advanced-development/data-models/relationships/page.mdx b/www/apps/book/app/learn/advanced-development/data-models/relationships/page.mdx index a33fc6990d908..8ecc950a274bc 100644 --- a/www/apps/book/app/learn/advanced-development/data-models/relationships/page.mdx +++ b/www/apps/book/app/learn/advanced-development/data-models/relationships/page.mdx @@ -179,6 +179,12 @@ The `pivotTable`, `joinColumn`, and `inverseJoinColumn` property are only availa + + +Following [Medusa v2.1.0](https://github.com/medusajs/medusa/releases/tag/v2.1.0), if `pivotTable`, `joinColumn`, and `inverseJoinColumn` aren't specified on either models, the owner is decided based on alphabetical order. So, in the example above, the `Order` data model would be the owner. + + + In this example, an order is associated with many products, and a product is associated with many orders. Since the `pivotTable`, `joinColumn`, and `inverseJoinColumn` configurations are defined on the order, it's considered the owner data model. ### Many-to-Many Relationship in the Database diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 55efbb544b2d0..ab8a217d3784a 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -45,7 +45,7 @@ export const generatedEditDates = { "app/learn/advanced-development/data-models/manage-relationships/page.mdx": "2024-09-10T11:39:51.167Z", "app/learn/advanced-development/modules/remote-query/page.mdx": "2024-07-21T21:20:24+02:00", "app/learn/advanced-development/modules/options/page.mdx": "2024-10-16T08:49:27.162Z", - "app/learn/advanced-development/data-models/relationships/page.mdx": "2024-11-27T16:05:55.995Z", + "app/learn/advanced-development/data-models/relationships/page.mdx": "2024-12-04T10:52:32.992Z", "app/learn/advanced-development/workflows/compensation-function/page.mdx": "2024-11-28T14:05:29.691Z", "app/learn/advanced-development/modules/service-factory/page.mdx": "2024-09-30T08:43:53.127Z", "app/learn/advanced-development/data-models/primary-key/page.mdx": "2024-09-30T08:43:53.123Z",