Tips for validating document references in Sanity.io
25 replies
Last updated: Mar 9, 2022
M
Hi there! I have a data model with two document types, foo and bar, and bar’s can contain references to multiple foos. We want to warn if any foo exists that isn’t referenced by at least one bar, but I’m not sure how to navigate references in validation. Is there a way in the validation of foo to say “referenced by at least one bar”?
Mar 8, 2022, 11:37 PM
It is possible! In this case, I'd probably use document-level validation in conjunction with the client.
validation: Rule => Rule.custom(async ({ _id }) => { //count the incoming references from Foo docs const referenceCount = await studioClient.fetch(`count(*[_type == 'foo' && references(${_id})])`) //Return error if 0 Foo docs reference Bar return referenceCount > 0 ? true : 'Document must have at least 1 Foo referencing it' }),
Mar 8, 2022, 11:51 PM
M
Ah makes total sense! I’ll give it a whirl. Thank you!
Mar 8, 2022, 11:53 PM
V
user M
Maybe a dumb question but if I don't ask, I don't know -- what happens with a false with document validation? You can't commit the change? Do we control the response, like if there's warning text? I couldn't tell from reading that.Mar 8, 2022, 11:56 PM
M
In my case, I’ll be adding .warning() and putting up warning text
Mar 8, 2022, 11:57 PM
M
By default, it would fail to publish I believe
Mar 8, 2022, 11:57 PM
J
By default it will give you an alert
!that the field isn’t valid, but you can also add a custom warning and nest a string or other error prop return as needed into that.
Mar 8, 2022, 11:58 PM
J
here’s a feedback example when a string doesn’t match the default url type pattern
Mar 8, 2022, 11:59 PM
V
Thank you both! Sounds like it extends the field-level dynamics and is just another way to call them up.
Mar 8, 2022, 11:59 PM
M
Okay a more generic question now that I’ve tried and failed to use Racheal’s snippit — any pro tips for debugging validation?
Mar 9, 2022, 12:00 AM
Yep! All of that is correct! There are different error levels that you can control. The validation I provided would prevent you from publishing a document (which may be a bad experience for your editors). As Matthew said, if you append
.warning()you would still be able to publish, but the document would indicate an issue.
Mar 9, 2022, 12:00 AM
user B
you likely need to bring in the client. Mine uses one that I preconfigure and reuse through my studio. Notice the studioClient.fetch(). Mine looks like this:
import client from "part:@sanity/base/client" export const studioClient = client.withConfig({apiVersion: '2021-03-25'})
import studioClient from './path/to/studioClient.js'
Mar 9, 2022, 12:02 AM
M
Makes total sense, but is there somewhere that I would have been able to debug that myself? Surprised I don’t see an error message anywhere in the studio about my validation query that definitely won’t work
Mar 9, 2022, 12:03 AM
I would think in your console it would tell you that studioClient is undefined.
Mar 9, 2022, 12:03 AM
M
Nothing in the console 😕
Mar 9, 2022, 12:04 AM
M
ahhhhh there it is
Mar 9, 2022, 12:05 AM
M
I’ve got that
Mar 9, 2022, 12:05 AM
M
My brain just filtered it out
Mar 9, 2022, 12:05 AM
M
Okay awesome, I can take it from here. Thanks for teaching me how to fish 😉
Mar 9, 2022, 12:05 AM
M
Phew, finally got it working! From your snippit I needed to change error. One follow up now that it’s working: I don’t see anything in the docs around the async + await syntax you used. Is that a sanity thing, or just generic javascript and I’m just a js newb?
references(${id})to
references('${id}')or I got a super unhelpful
expected ')' following function arguments
Mar 9, 2022, 12:39 AM
It's a general JS thing. There's a good explanation of the async and await keywords here .
Mar 9, 2022, 12:43 AM
J
It’s a typical js API rendering method Link and one of the more obscure and confounding things to learn, so don’t be embarrassed if it doesn’t come quickly or easily.
Mar 9, 2022, 12:43 AM
M
Thanks all!
Mar 9, 2022, 12:44 AM
J
Really great question
user B
- thank you!Mar 9, 2022, 12:46 AM
Sanity– build remarkable experiences at scale
Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.