Flatten a field value's relationships

default discord avatar
Alessio 🍣
2 months ago
31

Say I have a field value saved like this:


[
  {
    shop: {
      id: '63bb051e53c9a3b0f68c4a16',
      name: 'Amazon',
      createdAt: '2023-01-08T18:02:06.334Z',
      updatedAt: '2023-01-08T18:02:06.334Z'
    },
    link: 'https://www.amazon.ca/Sony-Alpha-A6400-Mirrorless-Camera/dp/B07MV3P7M8',
    link_affiliate: 'https://www.amazon.ca/Sony-Alpha-A6400-Mirrorless-Camera/dp/B07MV3P7M8',
    available: true,
    id: '63dbb707c766bf2123681699',
    price: 191.59,
    last_checked: 'Thu Mar 16 2023 15:52:48 GMT+0100 (Central European Standard Time)'
  }
]

I'd like to use it in a payload.update, but get the error "This field has the following invalid selections for the "shop" field.



I think instead of


shop: {


id: '63bb051e53c9a3b0f68c4a16',


name: 'Amazon',


createdAt: '2023-01-08T18:02:06.334Z',


updatedAt: '2023-01-08T18:02:06.334Z'


}


you'd need shop: '63bb051e53c9a3b0f68c4a16',



Is there a function to automatically flatten that?



or optimally a flag for payload.update to accept non flattened values



that'd really be best!

  • default discord avatar
    noheadphones
    2 months ago

    as in trying to migrate the data from one state to another?



    but no theres no function like that afaik

  • default discord avatar
    Alessio 🍣
    2 months ago

    Yep! Im getting the data with a higher depth, so that the shop is actually populated. And now I want to update it

  • default discord avatar
    noheadphones
    2 months ago

    hmm yeah no function as far as I know but im not sure how useful it would really be, seems like a utility something like lodash would provide, its too situational

  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    It may be possible to do transformations to the shape of the

    data

    for a relationship field before it updates, we may be able to handle this in Payload without changing the API at all. Where it gets hairy is when you have a relationship that is

    relationTo: ['many', 'different', 'collections']

    . It would take a little digging to see if this is feasible without adding too much complexity on the backend. I'd also have to think about how it could affect GraphQL mutations schemas.



    Lastly this change give me some concerns about what happens in existing hooks that may be impacted by this change, specifically plugins that exist and may not be written to handle different shapes of incoming relationship fields.

  • default discord avatar
    Alessio 🍣
    2 months ago

    So, some kind of

    if(relationship?.id){relationship = relationship?.id}

    check (at least for relations to only one collection) before anything happens to that data?



    Would be a nice QoL change! For me personally, I just manually set the shop to shop.id and it worked.



    If this happens before any update happened, how would it affect any hooks or plugins though? Wouldn't they just see the relationship: id value as always?

  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    I'm receptive to this idea because I had to write this portion of the docs because it was tripping people up:

    https://payloadcms.com/docs/fields/relationship#how-the-data-is-saved


    So you need to map objects to each of the 4 possible shapes expected to be recieved by Payload's update operation.



    It doesn't seem that bad.



    You're right that if the transformation happens early, like in the

    beforeOperation

    hook, you'd be safe on breaking changes.

  • default discord avatar
    Alessio 🍣
    2 months ago

    oh yea, had to do that in that pcms backpop plugin - was a bit annoying.



    What about transforming any of those shapes to one, uniform shape?



    So it always looks like this



    no matter if it's hasMany or just hasOne



    or polymorphic / non-polymorphic

    image.png
  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    That is an interesting idea. That would break existing hooks though.


    Honestly we should have done this from the beginning to avoid the problem where changing your config breaks existing data.

  • default discord avatar
    noheadphones
    2 months ago
    where changing your config breaks existing data

    the upcoming ORM work should help with this right? if you make automated db migrations with schema changes

  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    Yes true, but it is more stuff we have to handle in code and in running the migrations.


    The best code is the code you don't have to write.

  • default discord avatar
    noheadphones
    2 months ago

    Slightly related to the dev exp when dealing with object fields...you cant right now do just a partial update, eg for data:


    pricing: {
       price: 
       minimumPrice:
       currency:
    }

    with

    update

    if i want to change only one value i need to fill in the rest of the object too...so an update with


    pricing: {
      price:
    }

    doesnt work

  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    When you say object fields, you are talking about

    type: 'group'

    or is this more broad than that?

  • default discord avatar
    noheadphones
    2 months ago

    in this case specifically group yes, haven't encountered it with other fields as of yet

  • discord user avatar
    dribbens
    Payload Team
    2 months ago

    Probably the same for tabs with names, but I see your point. This should be opened as a new issue on github.

  • default discord avatar
    Alessio 🍣
    2 months ago

    @dribbens I made this a feature request:

    https://github.com/payloadcms/payload/discussions/2353

    Currently working with multiple, recursive relationships in a collection. Having to manually "flatten" those is a big, big, big pain, so I hope this can get added soon



    Additionally, I cannot "skip" updating those. If I have a

    tabs

    field with a name, it forces me to update it even if I don't want to



    so this



    Done:

    https://github.com/payloadcms/payload/issues/2354
  • default discord avatar
    noheadphones
    2 months ago

    got ahead of me, nice one

  • discord user avatar
    denolfe
    Payload Team
    2 months ago

    @noheadphones @Alessio 🍣 Update types updated to a deep partial and merged into master

    https://github.com/payloadcms/payload/pull/2407
  • default discord avatar
    Alessio 🍣
    2 months ago

    oh wow that was a simpler solution than what I expected - thank you!

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.