Skip to content

Instantly share code, notes, and snippets.

@m-alghobary
Created August 29, 2022 05:46
Show Gist options
  • Select an option

  • Save m-alghobary/e654dff2a27b4b4c65ac62fe16888a96 to your computer and use it in GitHub Desktop.

Select an option

Save m-alghobary/e654dff2a27b4b4c65ac62fe16888a96 to your computer and use it in GitHub Desktop.
A Laravel macro that adds a 'sync' method to the 'HasMany' relationship similar to the one on the 'BelongsTo' relationship.
<?php
namespace App\Providers;
use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasMany;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
}
public function boot()
{
HasMany::macro('sync', function (array $values = []) {
$newValues = collect($values);
$ids = collect($values)->pluck('id')->toArray();
$oldIds = $this->getResults()->pluck('id')->toArray();
$toDelete = array_diff($oldIds, $ids);
if ($toDelete > 0) {
$this->query->whereIn('id', $toDelete)->delete();
}
$relatedKey = explode('.', $this->foreignKey)[1];
$newValues->each(function ($value) use ($relatedKey) {
$finalValues = array_merge(Arr::except($value, ['id']), [$relatedKey => $this->parent->id]);
$this->related->updateOrCreate(
[$relatedKey => $this->parent->id, 'id' => $value['id'] ?? 0],
$finalValues
);
});
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment