How to prevent self-reference in child-parent setup in Sanity using custom validation or filter option.

4 replies
Last updated: Sep 7, 2023
Hi everyone, I'm new to Sanity trying to setup a child parent reference (category / subcategory) but how do I prevent a self reference?
AI Update

Great question! Preventing self-references in parent/child relationships is a common need. The good news is you can use the filter option on your reference field to exclude the current document.

Here's how to prevent a category from referencing itself as a subcategory:

{
  name: 'category',
  type: 'document',
  fields: [
    {
      name: 'title',
      type: 'string'
    },
    {
      name: 'parentCategory',
      type: 'reference',
      to: [{type: 'category'}],
      options: {
        filter: ({document}) => {
          return {
            filter: '_id != $id && !(_id in path("drafts.**"))',
            params: {
              id: document._id.replace(/^drafts\./, '')
            }
          }
        }
      }
    }
  ]
}

What's happening here:

  1. The filter option takes a function that receives the current document as context
  2. We return a GROQ filter that excludes documents where _id matches the current document's ID
  3. We use document._id.replace(/^drafts\./, '') to handle both draft and published versions
  4. The !(_id in path("drafts.**")) part ensures we're comparing against the published ID

Important notes:

  • Always check that document properties exist before using them (the example above assumes _id is always present, which it should be)
  • This filter only constrains the search results when selecting a reference—it doesn't validate existing references if you change the logic later
  • The filter uses the published document ID for comparison, which is what you want for referential integrity

This pattern works for any self-referential scenario where you need to prevent a document from referencing itself!

using custom validation. you can simply look at the document using context to determine if the category can be set. https://www.sanity.io/docs/validation#091e10f957aa
the third example down shows that the second parameter of the custom method is
context
Or use filter option on the reference object to filter out the current document’s id from the list.

https://www.sanity.io/docs/reference-type#filter-ebd7a95f9dc6
Thanks all,
user P
that was also the solution I found easiest:

filter: ({document}) => {
          return {
            filter: '!defined(parent) && _id != $id',
            params: {
              id: document._id
            },
          }
        }

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?