Storing referring document value as a field in the document it refers to
34 replies
Last updated: Jan 20, 2023
J
Hi! I’m trying to figure out how to store the value of a referring document as a field in the document to which it refers. More context in the thread. Thanks!
Jan 17, 2023, 10:47 PM
J
I’m trying to make a page builder where each “block” is a document type (like “Testimonial”, “CTA Banner” instead of just an object (in order to get the full pane editor and in order to make some of the documents easily available across multiple pages).
I want to clearly label the “single use” documents by the name of the page that references them using a field called “Block Location” which is a reference to my Pages documents. I have this working if I manually select the referring page in each block but I want it to be automatically filled by that relationship.
I know that technically a block could be referenced by multiple pages and I plan on handling that case differently so… if there are multiple referrers I’ll just want to autofill this field with the first from the array of referrers.
I want to clearly label the “single use” documents by the name of the page that references them using a field called “Block Location” which is a reference to my Pages documents. I have this working if I manually select the referring page in each block but I want it to be automatically filled by that relationship.
I know that technically a block could be referenced by multiple pages and I plan on handling that case differently so… if there are multiple referrers I’ll just want to autofill this field with the first from the array of referrers.
Jan 17, 2023, 10:49 PM
R
I may be misunderstanding, but would setting an initial value on the block to the correct reference work for you here?
Jan 17, 2023, 11:14 PM
J
Yes!
Jan 17, 2023, 11:14 PM
J
I’m just not sure how to write the initial value statement.
Jan 17, 2023, 11:14 PM
R
Ah, got it! I can help you put it together. Can you share your schema?
Jan 17, 2023, 11:15 PM
J
Yeah, here it is, might be a little messy … still figuring this stuff out 😅
Jan 17, 2023, 11:20 PM
J
user M
I just cleaned up ^this file so there’s not so much unrelated stuff in it. Let me know if there’s anything else you’d need to know. And thanks! 🙏Jan 18, 2023, 3:09 PM
J
user M
Just checking in in hopes this doesn’t get lost. (I know, you have tons of requests!! 😅)Jan 18, 2023, 6:18 PM
R
I’ll be able to circle back later this afternoon 🙂 just have to catch up on some stuff first.
Jan 18, 2023, 6:19 PM
J
Thanks!
Jan 18, 2023, 6:20 PM
R
Ok, thanks for your patience! Here’s an example of how an initial value would work:
import {defineField, defineType} from 'sanity' export default defineType({ name: 'testimonialBlock', title: 'Testimonial Block', type: 'document', fields: [ defineField({ title: 'Block Nickname', name: 'nickname', type: 'string', }), defineField({ title: 'Block Location', name: 'blockLocation', type: 'reference', to: [{type: 'page'}], options: { disableNew: true, }, initialValue: async (value, { getClient }) => { const client = getClient({ apiVersion: '2023-01-18' }); const _id = await client.fetch(`*[_type == 'yourType'][0]._id`) return { //return an object with the values you need _type: 'reference', _ref: _id }; }, }), defineField({ title: 'Quote', name: 'textBlocks', type: 'array', of: [{type: 'block'}], }), ], preview: { select: { nickname: 'nickname', location: 'blockLocation.title', }, prepare(selection) { const {nickname, location} = selection; let title = nickname; let blockType = 'Testimonial'; if (location) { title = location + ': ' + nickname; } return { title: title, subtitle: blockType } } } })
Jan 18, 2023, 8:27 PM
J
⚡️🎸🤘
Jan 18, 2023, 9:30 PM
J
It works!!!!! Thanks so much. 🙂
Jan 18, 2023, 9:30 PM
R
You’re welcome!
Jan 18, 2023, 10:03 PM
J
Awww man, my test was flawed and it actually didn’t fully work. 🤦♂️🤦♂️🤦♂️
It is setting the initial value to
a page but it’s not setting it to the page that referenced this document.
Do you know how I can update the query so that it specifically grabs the page that references this document?
It is setting the initial value to
a page but it’s not setting it to the page that referenced this document.
Do you know how I can update the query so that it specifically grabs the page that references this document?
Jan 18, 2023, 11:49 PM
J
I’m guessing I’ll be able to figure out a groq query to return pages that reference a particular document ID … but how do I get the ID of “this” document?
Jan 18, 2023, 11:50 PM
R
Ah, yeah, I should have clarified that you would need to tweak the query. What’s the type of the document you’re looking for? You’d need to change out the
'yourType'string in my example for that type. One thing that just occurred to me is that you need to get the current document id in order to find the referencing document in your query. I’m not sure how you’d do that since it’s not provided in the function’s context.
Jan 19, 2023, 12:13 AM
J
I had switched out
And I did get a query working to return the page:
'yourType'for my type (
page) and that’s why it started to work… but yeah, I’m not sure how to get the current document ID.
And I did get a query working to return the page:
*[_type == 'page' && references('dd4ec656-690e-46c9-bf4b-6ca405f893c2')][0]
Jan 19, 2023, 12:37 AM
J
Just need to swap out that id with a variable for the Current ID, if that’s possible.
Jan 19, 2023, 12:37 AM
J
Ah! Just realized that we can essentially set the initial value to the page that references the “current document” by finding the ID of the newest document of this type!
https://stackoverflow.com/questions/50154221/fetch-id-of-last-created-document-of-given-type-in-sanity
https://stackoverflow.com/questions/50154221/fetch-id-of-last-created-document-of-given-type-in-sanity
Jan 19, 2023, 5:18 PM
J
Seems like it’s working! 🙂
Jan 19, 2023, 5:18 PM
J
It could end up wrong if 10 people created a document at the same time but since it’s really just a field for labeling documents so it wouldn’t be a big problem if the initial value set was a miss on rare occasions.
Jan 19, 2023, 5:20 PM
R
Ah nice, that didn’t even occur to me!
Jan 19, 2023, 5:22 PM
J
It was a lucky google search on my part 😂
Jan 19, 2023, 5:22 PM
R
I have made an entire career of lucky google searches 😆
Jan 19, 2023, 5:23 PM
J
😂😂😂
Jan 19, 2023, 5:24 PM
J
On the off-chance you enjoy zombie requests (or at least hearing how it turned out) ……… I ended up ditching the above approach (sorting docs by
createdAt) because the new docs created through the reference (array) field didn’t have a
createdAtbefore at least getting some content to start saving them as drafts.
Jan 20, 2023, 12:28 AM
J
So you can’t really look up a page that references a newly initiated (but not yet created) doc that is seemingly unfindable except by ID. (Even when wildcard querying for everything.)
Jan 20, 2023, 12:29 AM
J
So instead I just decided to pop in the page that was most recently updated.
*[_type == 'page'] | order(_updatedAt desc) [0] ._id
Jan 20, 2023, 12:30 AM
J
Can’t add a document to a page without updating it(’s draft) so it seems to work reliably!
Jan 20, 2023, 12:30 AM
J
The other nice to have would be disabling the initalvalue when the docs are created outside of this context (being refernced from another doc). But from my searching that doesn’t seem to be an easy thing to check for.
Jan 20, 2023, 12:32 AM
R
Yeah, I’m hoping that behavior changes! I’d really like to be able to control initial values from the create-in-place reference schema.
Jan 20, 2023, 4:14 PM
J
For my particular case just having a reverse relationship seems like it could’ve also done the trick https://github.com/sanity-io/gatsby-source-sanity/issues/81
Jan 20, 2023, 4:16 PM
J
But yeah, I also like the idea of specific schema stuff for create-in-place.
Jan 20, 2023, 4:17 PM
Sanity– build remarkable experiences at scale
The Sanity Composable Content Cloud is the headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.