Back

Is there a shortcut for syncing one-to-many relationships?


thedamon posted 4 years ago

I see the sync function which is really handy for managing pivot table relationships.

I'm wondering about syncing one-many things.

Right now I have a form for adding videos, which each have X audio channels.

The way I am managing this right now is that the form has a hidden id field, so if the id is set the channel will be updated, and if it isn't, then a new channel will be added. so I can just call save() in a foreach and handle it.

I have to handle deleted channels as well, so I'm checking if there are any existing audiochannels not in the form's input and removing them.

Code would look mostly like this (not syntax checked):

foreach ($video->audiochannels as $key => $audiochannel){
    $audiochannel->save();
    $audiochannel_ids[] = $audiochannel->id;
}

$existing_channels = AudioChannels::where('video_id', $video->id);
foreach ($existing_channels as $audiochannel){
    if(!in_array($audiochannel->id), $audiochannel_ids){
        $audiochannel->delete();
    }
}

This works out ok, I'm just wondering if I'm missing something in the eloquent/laravel toolbox that's made to handle this.

codenamegary replied 4 years ago Solution

I don't think there's an existing sync function but it wouldn't be too terribly difficult to create one, probably a worthy addition to a hasMany relation.

However, you could simplify your code as-is using something like this...

$audiochannel_ids = array();
foreach ($video->audiochannels as $key => $audiochannel)
{
    $audiochannel->save();
    $audiochannel_ids[] = $audiochannel->id;
}

AudioChannels::where('video_id', $video->id)->whereNotIn('id', $audiochannel_ids)->delete();
Firtzberg replied 4 years ago

Looking for the same. BUT, instead of storing new records, and afterwards erasing those which are not new, I would prefer to erase all relevant data, and then store new records.

bruno-quintanilha replied 4 years ago

What about:

    $video->audiochannels()->delete();
    $video->audiochannels()->saveMany(// array of audiochannels);

Hope this helps


Sign in to participate in this thread!



We'd like to thank these amazing companies for supporting us