is it not possible to set a relation field to “required” as with the other field types?
e.g my Blog Collection has a field relation to Categories and Id like that category field to be set/selected to be mandatory.
But the relation field only offers unique and private as options.
If you want to enforce the user settings one or more relationships before the entity is saved, you can implement appropriate lifecycle methods (e.g. beforeCreate and beforeUpdate) for the model and throw an error if the relationship has not been set in the data/params that are passed into the methods. If you want to be able to set the error message you have to use the boom module to create a Boom error. e.g.:
const Boom = require('boom');
...
const err = new Error("Some useful message about the missing relation");
const boomError = Boom.boomify(err, {
statusCode: 422,
});
throw(boomError);
Obviously, this did not enforce at the database level - so manual sql inserts would still succeed.
Hi Hunter ! Thank you for your work-around. I would like apply this only when I’m in a ‘publish’ mode (not in draft mode). I don’t know how I get the document’s status value by using lifecycle methods… Do you have an idea ?
You should be able to look at the published_at property of the data argument for beforeCreate / beforeUpdate.
If published_at is null (for beforeCreate) or not set (for beforeUpdate) then the save is for a draft.
If the data argument for beforeUpdate has published_at with a valid date then the entity is being published (The Publish button was pressed). However, as you don’t get the entity’s other attributes passed in via data, you will probably have to load the existing entity (using the id from the params arg) and then check the relationship(s) that you want to enforce.
I tried to get the article and then check if the relation to article_category is defined.
Generally it’s really hard for me to debug the lifecycle-code. I insert some console.log but I don’t see them in browser or postman. Do you have any tip how to debug these hooks to see the console.log?
For debugging any Strapi server-side code I do the following (it gives you a full debugging experience):
Use VSCode to open the project
Open the terminal panel in VSCode (Terminal->New Terminal)
On the Top Righthand side from the dropdown menu, select “Create JavaScript Debug Terminal”
From that terminal run yarn strapi:develop
Open the javascript file and set a breakpoint (click in the left margin next to the line number) - a red dot will appear
Call the lifecycle event (via the browser or Postman etc)
The debugger will pause at the breakpoint and you can inspect all the variables, stack, etc.
Just a note:
The console events will be shown via the terminal that you use to run strapi (e.g. yarn strap:develop)
The example code you have looks like it is for a model that has draft publishing enabled. If you are not using draft, then you should check the data object directly for the relation(s). If you are using draft, you should check to see if the data is just the publish date (see previous comments I made)
If you only want to load one record, you can use .findOne(:id)
There are other ways to debug the server-side code, but I think this is the easiest to setup.
Hi, guys. Thank you all. This topic was very helpful for me.
async beforeUpdate(params, data) {
const news = await strapi.query("news-item").findOne({ id: params.id });
const newsUpdated = { ...news, ...data };
if (newsUpdated.published_at != null) {
if (newsUpdated.user == null) {
const err = new Error("Please set up User field");
const boomError = Boom.boomify(err, {
statusCode: 422,
});
throw boomError;
}
}
}
As @hunter says, I use Boom for error message in admin panel. But who can tell me, how can i hightlight that wrong field with red border or something like that?
Adding "required": true in content-types/your-content-type-name/schema.json does solve it. After that if you try to publish a post and a relation is required, it will not let you save/publish it and show an error that reads something like: