Multi tenant plugin and unique: true? #12604
-
Is it possible to have tenant level field uniqueness? Currently I have the setup like below but it only works at collection level and not tenant level. This leads to complications with users being unable to have share slugs between each other. fields: [
{
name: "slug",
type: "text",
required: true,
unique: true
}
] Is there a way for payload to automatically do this or do I have to setup some sort of custom validation calling the database to retrieve slugs from a collection scoped to current tenant? How would I even access the tenant to which a collection |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
After some digging I've found a solution. When using a multi-tenant plugin in PayloadCMS 3.0, Instead of using it I've created a fully type-safe and reusable function that does not hurt the DX one bit. I am pasting it here in case someone else runs into this problem in the future, as the current docs don't mention exactly how to handle tenant level uniqueness. export const checkFieldUniquePerTenant: Validate = async (
val,
{ data, path, collectionSlug, operation, previousValue },
) => {
try {
// we skip validation for read and delete operations
if (operation && ["read", "delete"].includes(operation)) {
return true;
}
// get the local api sdk client instance
const payload = await getPayloadClient();
// handle edge case if the user does not change the value but still saves the doc
if (operation === "update" && previousValue === val) {
return true;
}
// using payload.count we check if the document with same value and in same tenant group exists
const { totalDocs } = await payload.count({
collection: collectionSlug as CollectionSlug,
where: {
[`${path.join(".")}`]: {
equals: val,
},
tenant: {
equals: data.tenant,
},
},
});
// note: the only thing capitalize() function does is it makes the first letter capitalized.
// you can remove it or write your own custom logic for it
if (totalDocs > 0) {
return capitalize(
`${collectionSlug} with this ${path.join(".")} already exists`,
);
}
return true;
} catch (error) {
console.error(error);
return "Something went wrong";
}
}; Then we can just change all export const Page: CollectionConfig = {
slug: "page",
fields: [
{
name: "slug",
type: "text",
required: true,
// remove this
// unique: true,
// add this
validate: checkFieldUniquePerTenant,
},
],
}; |
Beta Was this translation helpful? Give feedback.
After some digging I've found a solution. When using a multi-tenant plugin in PayloadCMS 3.0,
unique: true
property becomes useless unless you don't want tenants sharing the values between each other, e.g. (tenant domains).Instead of using it I've created a fully type-safe and reusable function that does not hurt the DX one bit. I am pasting it here in case someone else runs into this problem in the future, as the current docs don't mention exactly how to handle tenant level uniqueness.