Expandability for custom fields with type `relation`
Is your feature request related to a problem? Please describe. Whenever I define a relation on an entity, a foreign key is created (duh), but I do not have the ability to specify what happens to the column (or row) when the referenced column is updated or deleted.
Let's say I have a plugin that has a custom field definition on the Product entity that relates to a custom entity:
{
type: "relation",
entity: RevenueGroup,
name: "revenueGroupId",
nullable: true,
public: false,
readonly: true,
}The custom entity definition looks like this:
import { DeepPartial, Product, VendureEntity } from "@vendure/core";
import { Column, Entity, Index, OneToMany } from "typeorm";
import { RevenueGroupKind } from "../generated-admin-types";
@Entity()
export class RevenueGroup extends VendureEntity {
constructor(input?: DeepPartial<RevenueGroup>) {
super(input);
}
@Column()
@Index({ unique: true })
code: number;
@Column({ nullable: true })
description: string;
@Column({
type: "enum",
enum: RevenueGroupKind,
default: RevenueGroupKind.GOODS,
nullable: false,
})
kind: RevenueGroupKind;
@OneToMany(() => Product, (product) => product.customFields.revenueGroupId)
products: Product[];
}This results in a column being created on the product entity like this:
ALTER TABLE
productADD CONSTRAINTFK_41a265244115fe63127e554b20cFOREIGN KEY (customFieldsRevenuegroupidid) REFERENCESrevenue_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION
I would like to be able to control what happens ON DELETE or ON UPDATE
Describe the solution you'd like
I would like the RelationCustomFieldConfig type/interface to support customizability for the ON DELETE and ON UPDATE options just like we can when defining relationships in (custom) entities through decorators.
An example type could look like this:
export type RelationCustomFieldConfig = TypedCustomFieldConfig<'relation', Omit<GraphQLRelationCustomFieldConfig, 'entity' | 'scalarFields'>> & {
entity: Type<VendureEntity>;
graphQLType?: string;
eager?: boolean;
inverseSide?: string | ((object: any) => any);
onDelete?: SomeType; // Typed to 'SET NULL' | 'CASCADE' | 'SET DEFAULT' etc..
onUpdate?: SomeType; // Typed to 'SET NULL' | 'CASCADE' | 'SET DEFAULT' etc..
};Describe alternatives you've considered
- a custom migration, and setting the custom field's type to
intbut that did not work like expected, because when developing locallysynchronizecannot be set totruesince the migration would just be undone (because schema mismatch). - I have tried setting
synchronizeto false and callingrunMigrations(config)before bootstrapping the application, but that resulted in warnings being printed to the console that I needed to create another migration to remove the foreign key:[server] Successfully ran migration: AddOnDeletionTriggerForRevenueGroups1742218462222 [server] Your database schema does not match your current configuration. Generate a new migration for the following changes: [server] - ALTER TABLE `product` DROP FOREIGN KEY `FK_RG_ID` - Single table inheritance.
Additional context
Source: vendurehq/vendure