orkhanahmadov's avatar

How to exclude models with relation data of null

So, I'm using polymorphic relation on User model. UserManager and UserAgent models related to User model with their own specific data. UserManager model has company_id, I'm using eager loading to filter models that only has one of the $companies values.

$companies = [1, 4];

$users = User::with(['userable' => function ($query) use ($companies) {
    $query->whereIn('company_id', $companies);
}])->whereUserableType(UserManager::class)->get();

This code works fine for filtering result, the only problem is is still returns models that doesn't match with the query, but they return as 'userable' = null. I know I can filter through those results like this:

function filterResult($data)
{
    for ($i = 0; $i < sizeof($data); $i++)
        if (is_null($data[$i]->userable))
            unset($data[$i]);

    return $data;
}

But is there any better way or maybe "Eloquent way" to filter out results with 'userable' = null value?

Thank you for your time.

0 likes
5 replies
martinbean's avatar
Level 80

@orkhanahmadov You could use the whereHas() method:

User::whereHas('userable')
    ->with(['userable' => function ($userable) use ($companies) {
        $userable->whereIn('company_id', $companies);
    }])
    ->whereUserableType(UserManager::class)
    ->get();
2 likes
orkhanahmadov's avatar

@martinbean Tried this already, but it shows SQL error:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'laravel_reserved_0.deleted_at' in 'where clause' (SQL: select * from users where exists (select * from users as laravel_reserved_0 where laravel_reserved_0.id = laravel_reserved_0.userable_id and laravel_reserved_0.deleted_at is null) and userable_type = App\UserManager and laravel_reserved_0.deleted_at is null)

users table has deleted_at column.

pakistanihaider's avatar

shared a piece of code below the comment.

I had the same issue, this is the way i am getting my records and sending those to the view.

These records do not include the null values, only the matched values are returned.

Route::get('/offers', function(){
    $offers = \App\Models\Issuers\Offer::with('offerStatus')->whereHas('offerStatus' , function ($offerStatus){
        $offerStatus->whereIn('name',['live', 'suspended', 'teaser','open']);
    })->get();
    return view('layouts/frontend/offers/index', compact('offers'));
});
2 likes

Please or to participate in this conversation.