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; });