It needs to think about this, for my situation, I need to query when audits table has any data, but the result requiring with it, so how to do this?

Here is my base query, it’s pretty basic, also I need search by specific term.

$histories = Product::when($no, function($query, $id) {
    return $query->where('id', 'like', "%{$id}%");
})->whereHas('audits', function ($query) use ($email) {
    $query->whereIn('url', ['orders', 'products'])
        ->latest('audits.id')
        ->when($email, function($query, $email) {
            return $query->join('users', 'users.id', '=', 'audits.user_id')->where('email', 'like', "%{$email}%");
        });
})

Next, append with conditions, also to know it, you need to tell with function condition( here is the key).

->with(['audits' => function($query) {
    $query->whereIn('url', ['orders', 'products']);
}])
->paginate((int)$request->get('per_page', 10));

It’s great! Also you can add macroable to AppServiceProvider.

        Builder::macro('withHas', function($relation, $constraint) {
            return $this->whereHas($relation, $constraint)->with([$relation => $constraint]);
        });

And then you can also do for this

Product::withHas('audits', function() { ... });

php – Merge ‘with’ and ‘whereHas’ in Laravel 5 – Stack Overflow