Merge pull request #15201 from Budibase/fix/views-with-hidden-relationships
Fix patching rows from views with hidden relationships
This commit is contained in:
commit
e2aed7e8c4
|
@ -52,10 +52,22 @@ export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
||||||
const table = await utils.getTableFromSource(source)
|
const table = await utils.getTableFromSource(source)
|
||||||
const { _id, ...rowData } = ctx.request.body
|
const { _id, ...rowData } = ctx.request.body
|
||||||
|
|
||||||
const dataToUpdate = await inputProcessing(
|
const beforeRow = await sdk.rows.external.getRow(table._id!, _id, {
|
||||||
|
relationships: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
let dataToUpdate = cloneDeep(beforeRow)
|
||||||
|
const allowedField = utils.getSourceFields(source)
|
||||||
|
for (const key of Object.keys(rowData)) {
|
||||||
|
if (!allowedField.includes(key)) continue
|
||||||
|
|
||||||
|
dataToUpdate[key] = rowData[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
dataToUpdate = await inputProcessing(
|
||||||
ctx.user?._id,
|
ctx.user?._id,
|
||||||
cloneDeep(source),
|
cloneDeep(source),
|
||||||
rowData
|
dataToUpdate
|
||||||
)
|
)
|
||||||
|
|
||||||
const validateResult = await sdk.rows.utils.validate({
|
const validateResult = await sdk.rows.utils.validate({
|
||||||
|
@ -66,10 +78,6 @@ export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
||||||
throw { validation: validateResult.errors }
|
throw { validation: validateResult.errors }
|
||||||
}
|
}
|
||||||
|
|
||||||
const beforeRow = await sdk.rows.external.getRow(table._id!, _id, {
|
|
||||||
relationships: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
const response = await handleRequest(Operation.UPDATE, source, {
|
const response = await handleRequest(Operation.UPDATE, source, {
|
||||||
id: breakRowIdField(_id),
|
id: breakRowIdField(_id),
|
||||||
row: dataToUpdate,
|
row: dataToUpdate,
|
||||||
|
|
|
@ -110,6 +110,21 @@ function fixBooleanFields(row: Row, table: Table) {
|
||||||
return row
|
return row
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSourceFields(source: Table | ViewV2): string[] {
|
||||||
|
const isView = sdk.views.isView(source)
|
||||||
|
if (isView) {
|
||||||
|
const fields = Object.keys(
|
||||||
|
helpers.views.basicFields(source, { visible: true })
|
||||||
|
)
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
|
const fields = Object.entries(source.schema)
|
||||||
|
.filter(([_, field]) => field.visible !== false)
|
||||||
|
.map(([columnName]) => columnName)
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
export async function sqlOutputProcessing(
|
export async function sqlOutputProcessing(
|
||||||
rows: DatasourcePlusQueryResponse,
|
rows: DatasourcePlusQueryResponse,
|
||||||
source: Table | ViewV2,
|
source: Table | ViewV2,
|
||||||
|
|
|
@ -1333,6 +1333,62 @@ if (descriptions.length) {
|
||||||
expect(resp.relationship.length).toBe(1)
|
expect(resp.relationship.length).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should be able to keep linked data when updating from views that trims links from the main table", async () => {
|
||||||
|
let row = await config.api.row.save(table._id!, {
|
||||||
|
name: "main",
|
||||||
|
description: "main description",
|
||||||
|
})
|
||||||
|
const row2 = await config.api.row.save(otherTable._id!, {
|
||||||
|
name: "link",
|
||||||
|
description: "link description",
|
||||||
|
relationship: [row._id],
|
||||||
|
})
|
||||||
|
|
||||||
|
const view = await config.api.viewV2.create({
|
||||||
|
tableId: table._id!,
|
||||||
|
name: "view",
|
||||||
|
schema: {
|
||||||
|
name: { visible: true },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const resp = await config.api.row.patch(view.id, {
|
||||||
|
_id: row._id!,
|
||||||
|
_rev: row._rev!,
|
||||||
|
tableId: row.tableId!,
|
||||||
|
name: "test2",
|
||||||
|
relationship: [row2._id],
|
||||||
|
})
|
||||||
|
expect(resp.relationship).toBeUndefined()
|
||||||
|
|
||||||
|
const updatedRow = await config.api.row.get(table._id!, row._id!)
|
||||||
|
expect(updatedRow.relationship.length).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should be able to keep linked data when updating from views that trims links from the foreign table", async () => {
|
||||||
|
let row = await config.api.row.save(table._id!, {
|
||||||
|
name: "main",
|
||||||
|
description: "main description",
|
||||||
|
})
|
||||||
|
const row2 = await config.api.row.save(otherTable._id!, {
|
||||||
|
name: "link",
|
||||||
|
description: "link description",
|
||||||
|
relationship: [row._id],
|
||||||
|
})
|
||||||
|
|
||||||
|
const view = await config.api.viewV2.create({
|
||||||
|
tableId: otherTable._id!,
|
||||||
|
name: "view",
|
||||||
|
})
|
||||||
|
await config.api.row.patch(view.id, {
|
||||||
|
_id: row2._id!,
|
||||||
|
_rev: row2._rev!,
|
||||||
|
tableId: row2.tableId!,
|
||||||
|
})
|
||||||
|
|
||||||
|
const updatedRow = await config.api.row.get(table._id!, row._id!)
|
||||||
|
expect(updatedRow.relationship.length).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
!isInternal &&
|
!isInternal &&
|
||||||
// MSSQL needs a setting called IDENTITY_INSERT to be set to ON to allow writing
|
// MSSQL needs a setting called IDENTITY_INSERT to be set to ON to allow writing
|
||||||
// to identity columns. This is not something Budibase does currently.
|
// to identity columns. This is not something Budibase does currently.
|
||||||
|
|
Loading…
Reference in New Issue