With that PR the content manager started submitting more complex object as the value for relations fields even if the value is empty. Unfortunately, this object passes through the required validator as it merely checks the value isn’t null or undefined.
BTW, if you implemented this check manually in your controllers and you really need to enforce this invariant you should consider if your check handles this new syntax. It goes roughly like this:
relation_attribute: {
connect: [<ids to attach>],
disconnect: [<ids to detach>)
}
Note that this syntax is “procedural” - it doesn’t state what the resulting data should be, but rather describes how to achieve the desired state by a set of updates. This makes a robust required check quite hard to pull-off as you’d have to first pull the current state of the entity from the DB, run the proposed updates, and only then check if the result is empty or not. If you think that embedding a procedural syntax inside a REST API is unfortunate well, you’re not alone.
You can follow the progress in the feature request: Specify relation column as required | Content Editing XP | Strapi I can’t give you an estimate, but we are currently exploring adding this option to relational fields and will notify you through the feature request.
Posting a solution for strapi versions above 4.5.0
To check if relation field is filled every time you change it you have to:
“check strapi data” - I check strapi data by doing this:
It goes through array of fields to “check” and it returns the field value if field was changed or false
This gets you a connect value, you only use disconnect in if statements below
in if statement you must use the data from
const { data } = event.params;
but in your validation logic you pass in checkedData, because you only validate it if it was disconnected
This is used in beforeUpdate lifecycle:
if(data.field_name.disconnect.length === 1 && data.field_name.connect.length === 0) {
if(!checkedData.field_name) {
throw new ForbiddenError('relation field is empty)
}
}
This is used in beforeCreate:
because if it wasn’t touched then you know it’s empty
if(data.field_name.disconnect.length === 0 && data.field_name.connect.length === 0) {
if(!checkedData.field_name) {
throw new ForbiddenError('relation field is empty)
}
}
This is such an important feature and it’s not implemented. Incredible.
To be specific, in Strapi 4.16.2 (the latest version at the time of writing this), adding the required: true to the relation attribute still does not prevent the creation of the entry in the interface, although the relation field has a red asterisk close to it, like normal required attributes have. This is strange because Strapi automatically updates the types once we do this. So, clearly, there’s a bug in Strapi, which has been around for so many versions and years, and the developers don’t seem to care. Moreover, in the interface, we cannot set this relation attribute to be required, like for normal attributes.