Merge branch 'linked-records' of github.com:Budibase/budibase into linked-records
This commit is contained in:
commit
3ddca769bb
|
@ -34,7 +34,11 @@ exports.save = async function(ctx) {
|
||||||
|
|
||||||
// rename record fields when table column is renamed
|
// rename record fields when table column is renamed
|
||||||
const { _rename } = modelToSave
|
const { _rename } = modelToSave
|
||||||
if (_rename) {
|
if (_rename && modelToSave.schema[_rename.updated].type === "link") {
|
||||||
|
throw "Cannot rename a linked field."
|
||||||
|
} else if (_rename && modelToSave.primaryDisplay === _rename.old) {
|
||||||
|
throw "Cannot rename the primary display field."
|
||||||
|
} else if (_rename) {
|
||||||
const records = await db.query(`database/all_${modelToSave._id}`, {
|
const records = await db.query(`database/all_${modelToSave._id}`, {
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
})
|
})
|
||||||
|
|
|
@ -38,12 +38,13 @@ function LinkDocument(
|
||||||
}
|
}
|
||||||
|
|
||||||
class LinkController {
|
class LinkController {
|
||||||
constructor({ instanceId, modelId, record, model }) {
|
constructor({ instanceId, modelId, record, model, oldModel }) {
|
||||||
this._instanceId = instanceId
|
this._instanceId = instanceId
|
||||||
this._db = new CouchDB(instanceId)
|
this._db = new CouchDB(instanceId)
|
||||||
this._modelId = modelId
|
this._modelId = modelId
|
||||||
this._record = record
|
this._record = record
|
||||||
this._model = model
|
this._model = model
|
||||||
|
this._oldModel = oldModel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -192,12 +193,12 @@ class LinkController {
|
||||||
* @returns {Promise<void>} The model has now been updated.
|
* @returns {Promise<void>} The model has now been updated.
|
||||||
*/
|
*/
|
||||||
async removeFieldFromModel(fieldName) {
|
async removeFieldFromModel(fieldName) {
|
||||||
let model = await this.model()
|
let oldModel = this._oldModel
|
||||||
let field = model.schema[fieldName]
|
let field = oldModel.schema[fieldName]
|
||||||
const linkDocs = await this.getModelLinkDocs(IncludeDocs.INCLUDE)
|
const linkDocs = await this.getModelLinkDocs(IncludeDocs.INCLUDE)
|
||||||
let toDelete = linkDocs.filter(linkDoc => {
|
let toDelete = linkDocs.filter(linkDoc => {
|
||||||
let correctFieldName =
|
let correctFieldName =
|
||||||
linkDoc.doc1.modelId === model._id
|
linkDoc.doc1.modelId === oldModel._id
|
||||||
? linkDoc.doc1.fieldName
|
? linkDoc.doc1.fieldName
|
||||||
: linkDoc.doc2.fieldName
|
: linkDoc.doc2.fieldName
|
||||||
return correctFieldName === fieldName
|
return correctFieldName === fieldName
|
||||||
|
@ -211,8 +212,8 @@ class LinkController {
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
// remove schema from other model
|
// remove schema from other model
|
||||||
let linkedModel = this._db.get(field.modelId)
|
let linkedModel = await this._db.get(field.modelId)
|
||||||
delete linkedModel[field.fieldName]
|
delete linkedModel.schema[field.fieldName]
|
||||||
this._db.put(linkedModel)
|
this._db.put(linkedModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,10 +247,10 @@ class LinkController {
|
||||||
/**
|
/**
|
||||||
* Update a model, this means if a field is removed need to handle removing from other table and removing
|
* Update a model, this means if a field is removed need to handle removing from other table and removing
|
||||||
* any link docs that pertained to it.
|
* any link docs that pertained to it.
|
||||||
* @param {object} oldModel The model before it was updated which can be used for differencing.
|
|
||||||
* @returns {Promise<Object>} The model which has been saved, same response as with the modelSaved function.
|
* @returns {Promise<Object>} The model which has been saved, same response as with the modelSaved function.
|
||||||
*/
|
*/
|
||||||
async modelUpdated(oldModel) {
|
async modelUpdated() {
|
||||||
|
const oldModel = this._oldModel
|
||||||
// first start by checking if any link columns have been deleted
|
// first start by checking if any link columns have been deleted
|
||||||
const newModel = await this.model()
|
const newModel = await this.model()
|
||||||
for (let fieldName of Object.keys(oldModel.schema)) {
|
for (let fieldName of Object.keys(oldModel.schema)) {
|
||||||
|
|
|
@ -33,24 +33,22 @@ exports.createLinkView = createLinkView
|
||||||
* @returns {Promise<object>} When the update is complete this will respond successfully. Returns the record for
|
* @returns {Promise<object>} When the update is complete this will respond successfully. Returns the record for
|
||||||
* record operations and the model for model operations.
|
* record operations and the model for model operations.
|
||||||
*/
|
*/
|
||||||
exports.updateLinks = async ({
|
exports.updateLinks = async function({
|
||||||
eventType,
|
eventType,
|
||||||
instanceId,
|
instanceId,
|
||||||
record,
|
record,
|
||||||
modelId,
|
modelId,
|
||||||
model,
|
model,
|
||||||
oldModel,
|
oldModel,
|
||||||
}) => {
|
}) {
|
||||||
// make sure model ID is set
|
if (instanceId == null) {
|
||||||
if (model != null) {
|
throw "Cannot operate without an instance ID."
|
||||||
modelId = model._id
|
|
||||||
}
|
}
|
||||||
let linkController = new LinkController({
|
// make sure model ID is set
|
||||||
instanceId,
|
if (modelId == null && model != null) {
|
||||||
modelId,
|
arguments[0].modelId = model._id
|
||||||
model,
|
}
|
||||||
record,
|
let linkController = new LinkController(arguments[0])
|
||||||
})
|
|
||||||
if (
|
if (
|
||||||
!(await linkController.doesModelHaveLinkedFields()) &&
|
!(await linkController.doesModelHaveLinkedFields()) &&
|
||||||
(oldModel == null ||
|
(oldModel == null ||
|
||||||
|
@ -67,7 +65,7 @@ exports.updateLinks = async ({
|
||||||
case EventType.MODEL_SAVE:
|
case EventType.MODEL_SAVE:
|
||||||
return await linkController.modelSaved()
|
return await linkController.modelSaved()
|
||||||
case EventType.MODEL_UPDATED:
|
case EventType.MODEL_UPDATED:
|
||||||
return await linkController.modelUpdated(oldModel)
|
return await linkController.modelUpdated()
|
||||||
case EventType.MODEL_DELETE:
|
case EventType.MODEL_DELETE:
|
||||||
return await linkController.modelDeleted()
|
return await linkController.modelDeleted()
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue