diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte index 5929b2db96..790a74df53 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte @@ -29,6 +29,12 @@ // Prevent modal closing if there were errors return false } + + if (rowResponse.status === 500) { + notifier.danger(rowResponse.message) + return false + } + notifier.success("Row saved successfully.") backendUiStore.actions.rows.save(rowResponse) } diff --git a/packages/server/src/constants/index.js b/packages/server/src/constants/index.js index ff2e6f19f0..90893730be 100644 --- a/packages/server/src/constants/index.js +++ b/packages/server/src/constants/index.js @@ -12,6 +12,11 @@ exports.FieldTypes = { AUTO: "auto", } +exports.RelationshipTypes = { + ONE_TO_MANY: "one-to-many", + MANY_TO_MANY: "many-to-many", +} + exports.AuthTypes = { APP: "app", BUILDER: "builder", diff --git a/packages/server/src/db/linkedRows/LinkController.js b/packages/server/src/db/linkedRows/LinkController.js index f51454d9e8..b01d5eede5 100644 --- a/packages/server/src/db/linkedRows/LinkController.js +++ b/packages/server/src/db/linkedRows/LinkController.js @@ -2,7 +2,7 @@ const CouchDB = require("../index") const { IncludeDocs, getLinkDocuments } = require("./linkUtils") const { generateLinkID } = require("../utils") const Sentry = require("@sentry/node") -const { FieldTypes } = require("../../constants") +const { FieldTypes, RelationshipTypes } = require("../../constants") const { isEqual } = require("lodash") /** @@ -163,8 +163,30 @@ class LinkController { ? linkDoc.doc2.rowId : linkDoc.doc1.rowId }) + + // if 1:N, ensure that this ID is not already attached to another record + const linkedTable = await this._db.get(field.tableId) + const linkedSchema = linkedTable.schema[field.fieldName] + // iterate through the link IDs in the row field, see if any don't exist already for (let linkId of rowField) { + if (linkedSchema.relationshipType === RelationshipTypes.ONE_TO_MANY) { + const links = await getLinkDocuments({ + appId: this._appId, + tableId: field.tableId, + rowId: linkId, + includeDocs: IncludeDocs.INCLUDE, + }) + + // The 1 side of 1:N is already related to something else + // You must remove the existing relationship + if (links.length > 0) { + throw new Error( + `1:N Relationship Error: Record already linked to another.` + ) + } + } + if (linkId && linkId !== "" && linkDocIds.indexOf(linkId) === -1) { // first check the doc we're linking to exists try {