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

Snapshot Laravel Package

oobook/snapshot

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require oobook/snapshot
    
  2. Publish Migrations & Config

    php artisan vendor:publish --tag="snapshot-migrations"
    php artisan vendor:publish --tag="snapshot-config"
    

    Run migrations:

    php artisan migrate
    
  3. Apply Trait to Model Add HasSnapshot trait to your Eloquent model:

    use Oobook\Snapshot\Concerns\HasSnapshot;
    
    class Product extends Model
    {
        use HasSnapshot;
    }
    

First Use Case: Creating a Snapshot

// Create a snapshot of an existing model
$product = Product::find(1);
$snapshot = $product->snapshot();

// Force sync relationships (optional)
$snapshot->syncSnapshot();

Implementation Patterns

Core Workflows

1. Snapshot Creation

  • Basic Snapshot:
    $snapshot = $model->snapshot();
    
  • Custom Snapshot Table: Configure in config/snapshot.php:
    'table' => 'custom_snapshots',
    
    Then use:
    $snapshot = $model->snapshot(['table' => 'custom_snapshots']);
    

2. Syncing Relationships

  • Automatic Sync: Enable in config:
    'sync_relationships' => true,
    
  • Manual Sync:
    $snapshot->syncSnapshot();
    

3. Querying Snapshots

  • Find snapshots for a model:
    $snapshots = Product::find(1)->snapshots();
    
  • Filter by timestamp:
    $snapshots = Product::find(1)->snapshots()->where('created_at', '>', now()->subDays(7));
    

4. Restoring from Snapshot

  • Restore attributes only:
    $snapshot->restore();
    
  • Force restore (overwrite existing data):
    $snapshot->forceRestore();
    

Integration Tips

1. Soft Deletes

If your model uses SoftDeletes, ensure the snapshot table includes deleted_at:

use Illuminate\Database\Eloquent\SoftDeletes;

class Product extends Model
{
    use HasSnapshot, SoftDeletes;
}

2. Observers

Trigger snapshots on model events (e.g., updating):

class ProductObserver
{
    public function updating(Product $product)
    {
        $product->snapshot();
    }
}

3. API Endpoints

Example Laravel route:

Route::post('/products/{id}/snapshot', function (Product $product) {
    return $product->snapshot();
});

4. Testing

Use snapshots in tests to isolate data:

public function test_snapshot_creation()
{
    $product = Product::factory()->create();
    $snapshot = $product->snapshot();

    $this->assertDatabaseHas('snapshots', [
        'snapshotable_id' => $product->id,
        'snapshotable_type' => Product::class,
    ]);
}

Gotchas and Tips

Pitfalls

1. Relationship Sync Issues

  • Problem: Relationships may not sync if the related models are not properly configured.
  • Fix: Ensure related models also use HasSnapshot or manually sync:
    $snapshot->syncSnapshot(['with' => ['category', 'tags']]);
    

2. Mass Assignment Risks

  • Problem: Snapshots may include sensitive data if guarded is not set.
  • Fix: Define $guarded in your model:
    protected $guarded = ['password', 'api_token'];
    

3. Performance Overhead

  • Problem: Syncing large relationships can be slow.
  • Fix: Disable automatic sync in config and manually trigger when needed:
    'sync_relationships' => false,
    

4. Timestamp Conflicts

  • Problem: If created_at/updated_at are manually set, snapshots may behave unexpectedly.
  • Fix: Use useTimestamps = false in the snapshot model or override:
    public function getSnapshotModel()
    {
        return \Oobook\Snapshot\Models\Snapshot::class;
    }
    

Debugging

1. Check Snapshot Table

Verify data exists:

\DB::table('snapshots')->where('snapshotable_id', $model->id)->get();

2. Log Sync Issues

Enable debug mode in config:

'debug' => true,

Check Laravel logs for sync errors.

3. Validate Relationships

Ensure polymorphic relationships are correctly defined:

public function snapshots()
{
    return $this->morphMany(\Oobook\Snapshot\Models\Snapshot::class, 'snapshotable');
}

Extension Points

1. Custom Snapshot Model

Extend the default snapshot model:

namespace App\Models;

use Oobook\Snapshot\Models\Snapshot as BaseSnapshot;

class Snapshot extends BaseSnapshot
{
    protected $casts = [
        'metadata' => 'array',
    ];
}

Override in your model:

public function getSnapshotModel()
{
    return \App\Models\Snapshot::class;
}

2. Add Custom Attributes

Attach metadata to snapshots:

$snapshot = $model->snapshot(['metadata' => ['user_id' => auth()->id()]]);

3. Hooks for Pre/Post Snapshot

Use model events:

class Product extends Model
{
    use HasSnapshot;

    protected static function booted()
    {
        static::creating(function ($model) {
            // Pre-snapshot logic
        });

        static::created(function ($model) {
            // Post-snapshot logic
        });
    }
}

4. Bulk Snapshots

Create snapshots for a collection:

$products = Product::all();
$snapshots = collect($products)->map->snapshot();
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums