Eloquent Secrets Intermediate Since Laravel 8.x

Model::toQuery()

Convert an Eloquent Collection back into a query builder scoped to those exact model IDs — bridging collections and queries.

Overview

toQuery() on an Eloquent Collection creates a new query builder instance constrained to the IDs of the models in that collection. This lets you perform further database operations (updates, deletes, aggregates) on a set of models you've already loaded.

Usage

$users = User::where('is_active', true)->get();

// ... do some in-memory filtering ...
$premiumUsers = $users->filter(fn ($user) => $user->isPremium());

// Convert back to a query for a bulk update
$premiumUsers->toQuery()->update(['receives_newsletter' => true]);

This generates:

UPDATE users SET receives_newsletter = 1 WHERE id IN (1, 5, 12, 34)

Real-World Examples

Bulk delete after complex in-memory filtering:

$orders = Order::where('status', 'pending')
    ->with('items')
    ->get();

$expiredOrders = $orders->filter(function ($order) {
    return $order->created_at->lt(now()->subDays(30))
        && $order->items->every(fn ($item) => $item->is_refundable);
});

$expiredOrders->toQuery()->delete();

Getting an aggregate from a subset:

$highValueOrders = $orders->filter(fn ($o) => $o->total > 1000);

$avgValue = $highValueOrders->toQuery()->avg('total');

When to Use

  • Performing bulk updates or deletes after in-memory filtering that can't be expressed in SQL
  • Getting aggregates from a subset of already-loaded models
  • Bridging the gap between "I filtered this in PHP" and "I need a DB operation on the result"