Merge pull request #15201 from Budibase/fix/views-with-hidden-relationships

Fix patching rows from views with hidden relationships
This commit is contained in:
Adria Navarro 2024-12-18 12:35:59 +01:00 committed by GitHub
commit e2aed7e8c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 85 additions and 6 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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.