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

Rewind Laravel Package

laragear/rewind

Rewind adds undo history to Laravel Eloquent models. It records model changes and lets you restore previous states, so you can safely revert updates, deletes, and other modifications through a simple API—ideal for audit trails, recovery, and user-facing undo features.

View on GitHub
Deep Wiki
Context7

Getting Started

Rewind adds a "time machine" for Eloquent models: it persists a snapshot of a model's attributes on every create/update/delete and lets you restore a record to a previous snapshot or point in time. That makes it a natural fit for admin dashboards, CMS editing flows, and any app where "undo my last change" is a real product requirement.

Minimal setup for v3.0.0:

  1. Install and publish. composer require laragear/rewind, then publish the migration and (optionally) the config:
    • php artisan vendor:publish --tag=rewind-migrations
    • php artisan vendor:publish --tag=rewind-config
    • php artisan migrate
  2. Look here first. The published config/rewind.php and the generated rewinds migration are the two files that tell you how v3 behaves — read them before touching application models. v3.0.0 is a major version bump from v2.0.0, so if you are upgrading, diff the published files against your existing copies rather than overwriting blindly.
  3. Add the trait. Apply the package's rewindable trait to each model you want tracked:
    use Laragear\Rewind\Rewindable;
    
    class Post extends Model
    {
        use Rewindable;
    }
    
  4. First use case. Save a model, edit it, then roll back:
    $post = Post::create(['title' => 'Draft']);
    $post->update(['title' => 'Final']);
    
    $post->rewind(); // restores the previous snapshot
    

Because v3.0.0's changelog is only a compare link, verify the exact trait namespace, config keys, and available rewind methods against the README/UPGRADING docs for this tag before relying on any single method name — those are the most likely surfaces to have moved between v2 and v3.

Implementation Patterns

Per-model trait tracking. The trait is the whole integration surface. Any model that needs history gets it; models that don't stay untouched. This is the cleanest way to keep the rewinds table scoped to records that actually matter.

Rewinding to a snapshot vs. a date. Day-to-day you'll typically use three shapes:

  • Last state — $model->rewind() for the common "undo the last save" case in an editor.
  • Specific snapshot — list a model's rewinds (via the history relationship exposed by the trait) and restore a chosen one; this is what backs a "Version history" UI.
  • Point in time — for incident response, restore a record to how it looked at a given moment.

Treat the exact method names as v3-specific and confirm them in the docs before building UI on top.

Admin/audit dashboards. Because each rewind record carries the full attribute payload, you can render a diff view ("what changed, when, by whom" — the actor is whatever you enrich your snapshot with) and give operators a one-click restore. Pair this with a normal audit log if you need immutable compliance records; rewinds are mutable history by design.

Bulk / operational rewinds. Rewinding is a write operation that should be deliberate. Wrap multi-model operations in a DB transaction so a partial failure doesn't leave related records in mismatched states.

Suppress tracking where it's noise. Seeders, factories, imports, and one-off data migrations will flood the table. Scope tracking off around those code paths (the trait exposes a without…-style escape hatch in v2/v3 — check the current name in the docs). This is the single most important pattern to bake into your base test case and seeders.

Retention scheduling. History grows monotonically. Add a scheduled prune (or your own where('created_at', '<', ...)->delete()) to the app's scheduler as part of rollout, not as an afterthought.

Composing with other Laragear packages. If you already use packages like Login Link, Gag, or Pwned Passwords, keep each package's config and publish tags separate; don't assume shared conventions across the family.

Gotchas and Tips

  • v3 is a breaking release. The compare link v2.0.0...v3.0.0 is your only changelog. Before upgrading production: publish the new migration into a scratch branch and diff it, re-read the config, and run the full test suite. Expect at minimum a new migration and possibly renamed config keys/methods.
  • Not every change is tracked. Query-builder bulk updates (Post::where(...)->update(...)), raw SQL, and insert bypass Eloquent model events, so they leave no rewind. Anything you need reversible must go through model instances.
  • Relationships are not cascaded. Rewinding a parent does not rewind children. If a Post has Comments, you must rewind each model that carries the trait.
  • Deletes and soft deletes. Deleting a tracked model stores a snapshot; restoring a deleted record depends on the package's delete handling and your soft-delete setup. Test delete → rewind → delete → force-delete explicitly, since this is where history tables usually surprise people.
  • Events and observers still fire. A rewind is a write to the model; observers, updated events, and downstream side effects run. Guard against infinite loops (an observer that writes → history → observer…) and against re-firing notifications on restore.
  • Config caching. After publishing config, php artisan config:clear — stale cached config is the usual reason tracking silently "stops working" after a deploy.
  • Timezone. Point-in-time restores compare against stored timestamps; make sure app.timezone and DB timezone agree, and be explicit about the comparison boundary (inclusive/exclusive).
  • Debugging checklist when a rewind doesn't appear: trait present on the model → migration run and rewinds table populated → model change went through Eloquent (not a bulk query) → tracking not suppressed in that scope → config cache cleared.
  • Extension points. Customize by overriding trait methods on the model, or by listening to the package's model events, rather than editing published files — keeps composer update clean for the next major.
  • Keep an eye on table size and index usage. If you build a "history" UI, index (rewindable_type, rewindable_id, created_at) early; a raw history table will scan painfully at scale.
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