Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Relations and Drafts

default discord avatar
xhomu3 years ago
11

Suppose I have two collections:



* Posts - has a relation with notes


* Notes - has versions & drafts enabled



When getting Posts, how do I get the Note drafts in the relation?



Is the only way to make another request for the Note directly for its draft versions?

  • default discord avatar
    princephpdev3 years ago
    versions: { drafts: true },

    @196889179391655936

    Please find the related Doc



    https://payloadcms.com/docs/versions/drafts#controlling-who-can-see-collection-drafts
  • default discord avatar
    xhomu3 years ago

    Sorry I wasn't being very clear.



    Post = {
        fields: [ 
            {   name: "notes",
                type: "relationship",
                relationTo: "notes",
                required: true,
                hasMany: true,
    ]
    }


    Notes is the one with drafts


    Note = {
    ...
    versions: {
            drafts: {
                autosave: {
                    interval: 2000,
                }
            },
            maxPerDoc: 20,
            retainDeleted: false,
        }
    }


    Now, if I just query post,



    await payload.findByID<Post>({
            collection: "posts",
            id: postId,
            user,
        });


    in post.notes, it would only return the published versions of notes.



    await payload.findByID<Post>({
            collection: "posts",
            id: postId,
            user,
            draft: true
        });

    doesn't work, since Posts aren't the one with draft versions.



    The only way I can work around that is do two queries:



        const post = await payload.findByID<Post>({
            collection: "posts",
            id: postId,
            user,
        });
    
        const notes = await Promise.all(
            post?.notes?.map((note) =>
                payload.findByID<Note>({
                    collection: "notes",
                    id: typeof note === "string" ? note : note.id,
                    draft: true,
                    user,
                })
            )
        );
  • default discord avatar
    princephpdev3 years ago

    Hi

    @196889179391655936

    , Can you try with access property in Notes, Like -



    access: { read: ({ req }) => { if (req.user) return true; return { or: [ { _status: { equals: 'published', }, }, { _status: { equals: 'draft', } } ] }; }, }; }, },

    Something like that

  • default discord avatar
    xhomu3 years ago

    Yes, I have a read access written for notes.



    Let me dig it up

  • default discord avatar
    princephpdev3 years ago

    Also you can use depth and where query



    const getPosts = async () => { const stringifiedQuery = qs.stringify({ where: query // ensure thatqsadds thewhereproperty, too! }, { addQueryPrefix: true }); const response = await fetch(http://localhost:3000/api/posts${stringifiedQuery}`);
    // Continue to handle the response below...
    }`
  • default discord avatar
    xhomu3 years ago

    This is access: read for notes


    export const isAdminorUserorPublished = (userField = 'user'): Access => ({ req: { user } }) => { 
         // Return true or false based on if the user has an admin role 
         if(user?.roles?.includes("admin")) return true; 
      
         // using a query constraint, we can restrict it based on the `user` field 
         if(user) return { 
             or: [ 
                 { 
                     [userField]:  { 
                     equals:  
                         user?.id 
                     } 
                 }, 
                 { 
                     _status: { 
                         equals'published' 
                     } 
                 }, 
                 { 
                     _status: { 
                         equalsfalse 
                     } 
                 } 
                 ] 
         } 
    
        //otherwise return published version only 
         return { 
             or: [ 
                 { 
                     _status: { 
                         equals'published' 
                     } 
                 }, 
                 { 
                     _status: { 
                         equalsfalse 
                     } 
                 } 
                 ] 
         } 
      
     };
     
  • default discord avatar
    princephpdev3 years ago

    Ok so there you have , if user status = published, you can remove that



    it will return all notes along with draft



    DId you tried that?



    Or use depth=2



    https://payloadcms.com/docs/getting-started/concepts#depth

    with where condition in api



    ?where[posts.notes.status][equals]=draft



    something like that

  • default discord avatar
    xhomu3 years ago

    Mmm, thanks for the hints! Will have to play with versions a bit more tomorrow.

  • default discord avatar
    princephpdev3 years ago

    Yes

  • default discord avatar
    xhomu3 years ago

    Are there any public repos with interesting access control rules that is worth checking out?



    Besides the official ones in payload GitHub? Already had those bookmarked.

  • default discord avatar
    princephpdev3 years ago

    Will check and get back to you.

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.