From 85f65670292292b2f852fa5381dfe6ed9bfae358 Mon Sep 17 00:00:00 2001 From: Jelle De Loecker Date: Mon, 18 Mar 2024 18:09:54 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Allow=20`Field.Enum`=20values=20tha?= =?UTF-8?q?t=20are=20used=20by=20a=20`Field.Schema`=20field=20to=20refer?= =?UTF-8?q?=20to=20a=20document=20in=20a=20model,=20as=20if=20they=20were?= =?UTF-8?q?=20an=20association?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + lib/app/helper_field/schema_field.js | 55 +++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab64a31..5cb53ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Add support for asynchronous custom schema values in the `Schema` field class * Make the `Controller#model` getter try to get the model from the same namespace * Use the correct model name (instead of constructor name) for schemas of a Route +* Allow `Field.Enum` values that are used by a `Field.Schema` field to refer to a document in a model, as if they were an association ## 1.4.0-alpha.3 (2024-02-25) diff --git a/lib/app/helper_field/schema_field.js b/lib/app/helper_field/schema_field.js index ed2577c..65fb27e 100644 --- a/lib/app/helper_field/schema_field.js +++ b/lib/app/helper_field/schema_field.js @@ -212,6 +212,17 @@ SchemaField.setMethod(function resolveSchemaPath(context_schema, record, field_p } else if (enum_value.schema) { schema = enum_value.schema; } else if (enum_value.value) { + + if (enum_value.value.via_model) { + // The value is actually referring to a specific record + return this.getSubschemaFromModel( + enum_value.value.via_model, + enum_value.value.foreign_key, + enum_value.value.pk || record_value, + property_name + ); + } + schema = enum_value.value[property_name] || enum_value.value.schema; } else { console.warn('Failed to find schema path', JSON.stringify(schema_path), 'in record', record); @@ -245,20 +256,44 @@ SchemaField.setMethod(function getSubschemaFromAssociation(record, path, associa return false; } - const associated_model = alchemy.getModel(association.model_name); + return this.getSubschemaFromModel( + association.model_name, + association.options.foreign_key, + local_value, + path + ); +}); + +/** + * Get the subschema via an association + * + * @author Jelle De Loecker + * @since 0.2.0 + * @version 1.4.0 + * + * @param {string} model_name + * @param {string} foreign_key + * @param {*} local_value + * @param {string} path The path inside the associated schema + * + * @return {Schema} Response might be a promise + */ +SchemaField.setMethod(function getSubschemaFromModel(model_name, foreign_key, local_value, path) { + + const model = alchemy.getModel(model_name); - if (!associated_model) { + if (!model) { return false; } - return Pledge.Swift.execute(async () => { + let remote_request = model.resolveRemoteSchemaRequest( + this, + foreign_key || '_id', + local_value, + path + ); - let result = await associated_model.resolveRemoteSchemaRequest( - this, - association.options.foreign_key, - local_value, - path - ); + return Pledge.Swift.waterfall(remote_request, result => { if (!result) { return null; @@ -269,7 +304,7 @@ SchemaField.setMethod(function getSubschemaFromAssociation(record, path, associa return result; } - let found_schema = this.resolveSchemaPath(associated_model.schema, result, path, path); + let found_schema = this.resolveSchemaPath(model.schema, result, path, path); return found_schema; });