Query related models located on different database connections using whereHas() without cross-database join errors.
When your application partitions data across multiple database connections (such as separating analytics logs, multi-tenant tenants, or payment microservices onto different database servers), standard SQL joins between connection tables fail.
Eloquent's whereHas() directly handles relations across different database connections.
Defining Models on Separate Connections
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Tenant extends Model
{
protected $connection = 'main_db';
public function activityLogs(): HasMany
{
return $this->hasMany(ActivityLog::class);
}
}
class ActivityLog extends Model
{
// Stored on a separate logging database server
protected $connection = 'logging_db';
}
Querying Across Connections with whereHas()
use App\Models\Tenant;
// Eloquent handles the cross-connection query correctly
$activeTenants = Tenant::whereHas('activityLogs', function ($query) {
$query->where('created_at', '>=', now()->subDays(7));
})->get();
Summary
- Enables relational querying even when models reside on distinct database servers.
- Uses
WHERE EXISTSqueries scoped by database name. - Eliminates manual cross-database ID querying loops.
Related Tips
View all tips →Refresh and Pessimistically Lock Models with refreshForUpdate() in Laravel 13.27
Laravel 13.27 adds refreshForUpdate(), reloading an existing model instance in-place with fresh database attributes while acquiring an exclusive FOR UPDATE row lock.
Scope Pivot Table Queries with Closures in wherePivot() in Laravel 13.26
Laravel 13.26 allows wherePivot() and orWherePivot() to accept closures, enabling direct reuse of local scopes defined on custom Pivot models.