fix: Unique constraint should account for soft deleted records (#11048)
FIXES FRMW-2878 **What** Currently, the `one-to-one` unique constraints does not account for deleted record. This prevents from inserting a new record wth the same fk if another one is deleted. **Caveat** `hasOne` with FK option is meant to be a special case, for example a many to one - one to many without defining the other side of the relation. In that case we don't handle this behaviour and keep it as it is
This commit is contained in:
committed by
GitHub
parent
ecc8efcb04
commit
da3906efa4
@@ -3094,6 +3094,7 @@ describe("Entity builder", () => {
|
||||
owner: true,
|
||||
kind: "1:1",
|
||||
cascade: ["persist", "soft-remove"],
|
||||
unique: false,
|
||||
},
|
||||
user_id: {
|
||||
columnType: "text",
|
||||
@@ -3208,6 +3209,7 @@ describe("Entity builder", () => {
|
||||
name: "email",
|
||||
entity: "Email",
|
||||
fieldName: "email_id",
|
||||
unique: false,
|
||||
},
|
||||
email_id: {
|
||||
columnType: "text",
|
||||
@@ -3320,6 +3322,7 @@ describe("Entity builder", () => {
|
||||
entity: "Email",
|
||||
nullable: true,
|
||||
fieldName: "emails_id",
|
||||
unique: false,
|
||||
},
|
||||
emails_id: {
|
||||
columnType: "text",
|
||||
@@ -3423,6 +3426,7 @@ describe("Entity builder", () => {
|
||||
entity: "Email",
|
||||
mappedBy: "owner",
|
||||
fieldName: "email_id",
|
||||
unique: false,
|
||||
},
|
||||
email_id: {
|
||||
columnType: "text",
|
||||
@@ -3530,6 +3534,7 @@ describe("Entity builder", () => {
|
||||
cascade: ["persist", "soft-remove"],
|
||||
mappedBy: "user",
|
||||
fieldName: "email_id",
|
||||
unique: false,
|
||||
},
|
||||
email_id: {
|
||||
columnType: "text",
|
||||
@@ -3707,6 +3712,7 @@ describe("Entity builder", () => {
|
||||
cascade: ["persist", "soft-remove"],
|
||||
mappedBy: "user",
|
||||
fieldName: "email_id",
|
||||
unique: false,
|
||||
},
|
||||
email_id: {
|
||||
columnType: "text",
|
||||
@@ -3791,6 +3797,7 @@ describe("Entity builder", () => {
|
||||
kind: "1:1",
|
||||
cascade: ["persist", "soft-remove"],
|
||||
fieldName: "user_id",
|
||||
unique: false,
|
||||
},
|
||||
user_id: {
|
||||
columnType: "text",
|
||||
@@ -4125,8 +4132,8 @@ describe("Entity builder", () => {
|
||||
expect(settingMetadata.indexes).toEqual([
|
||||
{
|
||||
expression:
|
||||
'CREATE INDEX IF NOT EXISTS "IDX_setting_user_id" ON "setting" (user_id) WHERE deleted_at IS NULL',
|
||||
name: "IDX_setting_user_id",
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_setting_user_id_unique" ON "setting" (user_id) WHERE deleted_at IS NULL',
|
||||
name: "IDX_setting_user_id_unique",
|
||||
},
|
||||
{
|
||||
expression:
|
||||
@@ -4739,6 +4746,7 @@ describe("Entity builder", () => {
|
||||
mappedBy: "email",
|
||||
onDelete: undefined,
|
||||
owner: true,
|
||||
unique: false,
|
||||
},
|
||||
user_id: {
|
||||
kind: "scalar",
|
||||
@@ -4953,6 +4961,7 @@ describe("Entity builder", () => {
|
||||
onDelete: undefined,
|
||||
mappedBy: "email",
|
||||
owner: true,
|
||||
unique: false,
|
||||
},
|
||||
user_id: {
|
||||
kind: "scalar",
|
||||
@@ -5572,6 +5581,7 @@ describe("Entity builder", () => {
|
||||
mappedBy: "email",
|
||||
onDelete: undefined,
|
||||
owner: true,
|
||||
unique: false,
|
||||
},
|
||||
user_id: {
|
||||
kind: "scalar",
|
||||
@@ -5772,6 +5782,7 @@ describe("Entity builder", () => {
|
||||
mappedBy: "email",
|
||||
onDelete: undefined,
|
||||
owner: true,
|
||||
unique: false,
|
||||
},
|
||||
user_id: {
|
||||
kind: "scalar",
|
||||
@@ -5995,6 +6006,7 @@ describe("Entity builder", () => {
|
||||
nullable: false,
|
||||
onDelete: undefined,
|
||||
owner: true,
|
||||
unique: false,
|
||||
},
|
||||
parent_id: {
|
||||
name: "parent_id",
|
||||
|
||||
@@ -178,6 +178,7 @@ export function defineHasOneRelationship(
|
||||
*/
|
||||
export function defineHasOneWithFKRelationship(
|
||||
MikroORMEntity: EntityConstructor<any>,
|
||||
entity: DmlEntity<any, any>,
|
||||
relationship: RelationshipMetadata,
|
||||
{ relatedModelName }: { relatedModelName: string },
|
||||
cascades: EntityCascades<string[], string[]>
|
||||
@@ -198,6 +199,7 @@ export function defineHasOneWithFKRelationship(
|
||||
fieldName: foreignKeyName,
|
||||
...(relationship.nullable ? { nullable: relationship.nullable } : {}),
|
||||
...(mappedBy ? { mappedBy } : {}),
|
||||
unique: false,
|
||||
//orphanRemoval: true,
|
||||
} as OneToOneOptions<any, any>
|
||||
|
||||
@@ -508,6 +510,10 @@ export function defineBelongsToRelationship(
|
||||
mappedBy: mappedBy,
|
||||
fieldName: foreignKeyName,
|
||||
owner: true,
|
||||
/**
|
||||
* If we decide to support non soft deletable then this should be true and the unique index id should be removed
|
||||
*/
|
||||
unique: false,
|
||||
// orphanRemoval: true,
|
||||
}
|
||||
|
||||
@@ -523,6 +529,7 @@ export function defineBelongsToRelationship(
|
||||
{
|
||||
on: [foreignKeyName],
|
||||
where: "deleted_at IS NULL",
|
||||
unique: true,
|
||||
},
|
||||
])
|
||||
|
||||
@@ -821,6 +828,7 @@ export function defineRelationship(
|
||||
case "hasOneWithFK":
|
||||
defineHasOneWithFKRelationship(
|
||||
MikroORMEntity,
|
||||
entity,
|
||||
relationship,
|
||||
relatedEntityInfo,
|
||||
cascades
|
||||
|
||||
@@ -59,7 +59,7 @@ export function defineMikroOrmCliConfig(
|
||||
user: "postgres",
|
||||
password: "",
|
||||
...(options as any),
|
||||
entities,
|
||||
entities: entities.filter(Boolean),
|
||||
migrations: {
|
||||
generator: CustomTsMigrationGenerator,
|
||||
...options.migrations,
|
||||
|
||||
Reference in New Issue
Block a user