Weave Code
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 Serialize Laravel Package

anourvalar/eloquent-serialize

Serialize and restore Laravel Eloquent QueryBuilder instances. Save complex queries (with relations, where clauses, limits, etc.) to an array/package and later unserialize back into a builder to run the query again. Supports Laravel 6–12.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require anourvalar/eloquent-serialize
    

    No additional configuration is required for basic usage.

  2. First Use Case: Serialize a simple query for caching or deferred execution:

    use AnourValar\EloquentSerialize\EloquentSerialize;
    
    // Serialize a query
    $serialized = EloquentSerialize::serialize(
        \App\User::query()
            ->where('active', true)
            ->limit(10)
    );
    
    // Store $serialized in cache/Redis or pass to a queue job
    
    // Later, deserialize and execute
    $builder = EloquentSerialize::unserialize($serialized);
    $users = $builder->get();
    
  3. Where to Look First:

    • README.md: Focus on the serialize() and unserialize() methods.
    • Tests: Check the package’s test suite (tests/ directory) for edge cases and supported query types.
    • Laravel Logs: Monitor for EloquentSerialize exceptions during deserialization (e.g., schema mismatches).

Implementation Patterns

Usage Patterns

1. Caching Query Results

Cache serialized queries for high-traffic endpoints (e.g., API paginated lists):

$cacheKey = 'users_active_paginated';
$serialized = cache()->get($cacheKey);

if (!$serialized) {
    $serialized = EloquentSerialize::serialize(
        \App\User::query()
            ->where('active', true)
            ->paginate(20)
    );
    cache()->put($cacheKey, $serialized, now()->addHours(1));
}

$builder = EloquentSerialize::unserialize($serialized);
return $builder->get();

2. Deferred Execution with Queues

Offload query execution to background jobs (e.g., nightly reports):

// In your controller/route
dispatch(new SerializeAndQueueJob($serializedQuery));

// Job class
class SerializeAndQueueJob implements ShouldQueue {
    public function __construct(public string $serializedQuery) {}

    public function handle() {
        $builder = EloquentSerialize::unserialize($this->serializedQuery);
        $results = $builder->get();

        // Process results (e.g., send email, update analytics)
    }
}

3. Multi-Tenant Query Serialization

Serialize tenant-scoped queries to avoid rebuilding filters:

$tenantId = auth()->user()->tenant_id;
$serialized = EloquentSerialize::serialize(
    \App\User::query()
        ->where('tenant_id', $tenantId)
        ->with(['orders', 'subscriptions'])
);

// Reuse $serialized across requests/services

4. Feature Flagging for Dynamic Queries

Toggle query logic via feature flags without code changes:

if (featureEnabled('premium_dashboard')) {
    $serialized = EloquentSerialize::serialize(
        \App\User::query()
            ->with(['premiumOrders', 'analytics'])
            ->whereHas('premiumSubscription')
    );
} else {
    $serialized = EloquentSerialize::serialize(
        \App\User::query()
            ->with(['orders', 'basicAnalytics'])
    );
}

5. Data Portability for Analytics

Export query logic to third-party tools:

$queryLogic = EloquentSerialize::serialize(
    \App\Order::query()
        ->whereYear('created_at', now()->year)
        ->with(['user', 'items'])
);

// Send $queryLogic to a BI tool (without exposing DB credentials)

Workflows

Cache Warmup Strategy

Pre-serialize and cache queries during low-traffic periods:

// In a scheduled command (e.g., Artisan command)
public function handle() {
    $serialized = EloquentSerialize::serialize(
        \App\Product::query()
            ->with(['reviews', 'inventory'])
            ->orderBy('created_at', 'desc')
    );
    cache()->forever('products_featured', $serialized);
}

Schema-Agnostic Serialization

Validate schema before unserializing to handle DB changes:

$builder = EloquentSerialize::unserialize($serialized);
$this->validateSchema($builder); // Custom method to check columns/tables

if ($this->schemaValid) {
    $results = $builder->get();
} else {
    throw new \RuntimeException("Schema mismatch for serialized query.");
}

Partial Serialization

Serialize only specific parts of a query for flexibility:

$baseQuery = \App\User::query()->where('active', true);
$serializedWhere = EloquentSerialize::serialize($baseQuery->where('role', 'admin'));

// Later, merge with dynamic conditions
$builder = EloquentSerialize::unserialize($serializedWhere);
$builder->where('created_at', '>', now()->subYear());

Integration Tips

Laravel Cache Integration

Use Laravel’s cache drivers (Redis, Memcached) for serialized queries:

$serialized = EloquentSerialize::serialize(
    \App\Post::query()
        ->where('published', true)
        ->orderBy('views', 'desc')
);
cache()->put('trending_posts', $serialized, now()->addMinutes(5));

Queue Job Payloads

Store serialized queries in job payloads for async processing:

// Job
public function handle() {
    $builder = EloquentSerialize::unserialize($this->serializedQuery);
    $data = $builder->get()->toArray();

    // Process $data (e.g., generate PDF, update cache)
}

API Response Caching

Cache serialized API responses to reduce DB load:

Route::get('/users', function () {
    $cacheKey = 'api_users_list';
    $serialized = cache()->get($cacheKey);

    if (!$serialized) {
        $serialized = EloquentSerialize::serialize(
            \App\User::query()
                ->with(['posts', 'roles'])
                ->paginate(15)
        );
        cache()->put($cacheKey, $serialized, now()->addMinutes(10));
    }

    return EloquentSerialize::unserialize($serialized)->get();
});

Testing Serialized Queries

Mock serialized queries in unit tests:

public function test_serialized_query() {
    $serialized = EloquentSerialize::serialize(
        \App\User::query()->where('name', 'John')
    );

    $builder = EloquentSerialize::unserialize($serialized);
    $result = $builder->get();

    $this->assertCount(1, $result);
}

Gotchas and Tips

Pitfalls

1. Schema Mismatches

  • Issue: Deserializing a query against a changed schema (e.g., dropped columns, renamed tables) causes failures.
  • Fix: Validate schema before execution:
    $builder = EloquentSerialize::unserialize($serialized);
    if (!$this->checkSchemaCompatibility($builder)) {
        throw new \RuntimeException("Query incompatible with current schema.");
    }
    
  • Tip: Use Laravel’s Schema facade to verify column/table existence:
    private function checkSchemaCompatibility($builder) {
        foreach ($builder->getQuery()->columns as $column) {
            if (!$this->schema->hasColumn($builder->getModel()->getTable(), $column)) {
                return false;
            }
        }
        return true;
    }
    

2. Unsupported Query Features

  • Issue: Complex queries (e.g., raw SQL, custom accessors, or unsupported methods like selectRaw()) may fail to serialize.
  • Fix: Test with your query patterns and extend the package if needed:
    // Example: Extend for custom accessors
    EloquentSerialize::extend(function ($serializer) {
        $serializer->addIgnoredMethod('customAccessor');
    });
    
  • Tip: Check the package’s test suite for supported methods (e.g., where(), with(), orderBy()).

3. Performance Overhead

  • Issue: Serialization adds latency, especially for large datasets or complex relationships.
  • Fix: Benchmark and cache serialized queries:
    // Avoid serializing for real-time paths
    if (request()->wantsJson() && !cache()->has('serialized_query')) {
        // Use fresh query instead
    }
    
  • Tip: Use Redis for low-latency caching of serialized queries.

4. Global Scopes and Local Scopes

  • Issue: Global/local scopes may not serialize correctly, altering query behavior.
  • Fix: Explicitly handle scopes during serialization:
    $query = \App\User::query()->withoutGlobalScopes(['SoftDeletes']);
    $serialized = EloquentSerialize::serialize
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor