Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Eloquent Sync Laravel Package

xedi/eloquent-sync

xedi/eloquent-sync is a Laravel package for keeping Eloquent models synchronized with external systems. It helps map model data, push and pull changes, and keep local records consistent with remote sources, reducing custom integration boilerplate for sync workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require xedi/eloquent-sync. There is no Laravel auto-discovery guarantee on modern versions — if the service provider isn't registered automatically, add it manually in config/app.php.
  • Open the package source first (vendor/xedi/eloquent-sync/src) before trusting the README. With 1 star, 0 dependents, and a last release from June 2020, the code is the source of truth — confirm the trait name, the method signature, and whether sync() is exposed on the relationship or on the parent model.
  • The intended entry point mirrors BelongsToMany::sync(): attach it to a parent model that owns a hasMany, then call:
    $user->posts()->sync([$postA->id, $postB->id]);
    
    or, if the package exposes it on the model instead of the relationship:
    $user->sync('posts', [$postA->id, $postB->id]);
    
  • First real use case: reconciling a child collection from a form submission — e.g. a "user's posts" checklist where the submitted IDs should become the exact set of rows owned by the user, with removed rows reassigned or deleted.

Implementation Patterns

  • Form reconciliation. In a controller, validate the array first ('post_ids' => ['array'], 'post_ids.*' => ['integer', 'exists:posts,id']), then call sync() inside a DB::transaction(...) so a partial sync can't leave orphaned or misassigned rows.
  • Explicit trait on the parent. Add the package trait to every model that owns a hasMany you intend to sync. Keep it centralized in a BaseModel only if you're confident the trait doesn't override conflicting relationship behaviour.
  • Treat it as "reassign + prune." The value of this package over vanilla Eloquent is that hasMany doesn't ship with sync(). Expect the implementation to update the foreign key on the given IDs to the parent and nullify/delete the ones that fall out. Mirror that expectation in your tests.
  • Combine with firstOrCreate loops when syncing new children, not just existing ones — the package syncs existing rows by key; creation is usually your responsibility:
    DB::transaction(function () use ($user, $data) {
        $ids = collect($data)->map(fn ($p) => $user->posts()->firstOrCreate(['slug' => $p['slug']], $p)->id);
        $user->posts()->sync($ids);
    });
    
  • API/JSON endpoints. Accept a post_ids array, validate, sync, then $user->load('posts') and return the fresh relation. Because the underlying foreign key updates may bypass model events (see gotchas), reload from the DB rather than trusting in-memory state.
  • Chunk large sets. If you're syncing thousands of child IDs, chunk the array (e.g. collect($ids)->chunk(500)) — most implementations issue per-row updates, which is fine for form-sized data and painful for bulk imports.

Gotchas and Tips

  • Maintenance risk is the headline gotcha. Last release 2020-06-09, 1 star, 0 dependents. Before adopting, grep the source for Illuminate version constraints in composer.json. If it pins Laravel 5.x/6.x, you're on your own for 8/9/10/11 support. Pin the dependency and write a contract test covering the exact sync semantics you rely on, so a future framework upgrade fails loudly rather than silently mangling foreign keys.
  • sync() is destructive. Any child row whose ID isn't in the array will be detached or deleted depending on the implementation. Never call it without DB::transaction and never pass user input straight through without an exists validation rule — otherwise a malformed payload quietly wipes a relation.
  • Model events may not fire. If the package syncs via query-builder update()/delete(), saved, updated, and deleted events on the child models will be skipped, breaking observers, search indexing, cache invalidation, and activity logging. Watch a child model's updating/deleting hooks in a tinker session to confirm what actually fires before wiring observers.
  • Soft deletes. Confirm whether "removed" children are hard-deleted or soft-deleted. If children use SoftDeletes and the package bypasses Eloquent, you can get permanently truncated rows where you expected a soft delete. This is the difference between a recoverable mistake and a data incident.
  • Foreign key constraints. Syncing that nullifies the foreign key requires a nullable column; syncing that deletes requires onDelete('cascade') or a manual cleanup. Check your migration before trusting the package's default behaviour.
  • Debugging. Wrap the call and log DB::listen output — you'll see exactly which rows the package touches and in what order. If sync silently no-ops, the most common causes are a missing trait on the parent, the relationship not being named exactly as the package expects, or a guard/fillable issue preventing the foreign key from being set.
  • Extension point. If the package's semantics don't match yours (e.g. you want to reassign to a different parent instead of delete), fork the trait or subclass the relationship rather than patching vendor code. Given the maintenance state, a small local trait wrapping Eloquent (update the kept IDs, whereNotIn(...)->delete() the rest) is often a more durable choice than a 2020 dependency — evaluate it against your actual risk tolerance before shipping.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource