php - Laravel - order collection by relatioship

I have collection that I need to order like this:

  • So if my Model has that relationship it needs to be first on a list
  • If my Model does not have that relationship it needs to list after the Model that has relatioship

Here is my relationship function:

public function adMegaPremiumAdObjects()
    {
        return $this->hasMany(MegaPremiumAdObject::class, 'ad_id', 'id');
    }

And with this I can only order my collection with fields inside that table:

public function index()
    {
        $collection = AdObject::orderBy('some_field', 'DESC')->get();
    }

So I need to order this collection by my relationship adMegaPremiumAdObjects - if some Model have that relationship it needs to show first in a list.

If I try with whereHas it only shows me collection with that relationship and that doesn't help me.

How can I do that?

Answer

Solution:

You can use withCount() to add a relation count column, which you can order by:

$collection = AdObject::withCount('adMegaPremiumAdObjects')->orderBy('adMegaPremiumAdObjects_count', 'DESC')->get();

From Laravel docs:

If you want to count the number of results from a relationship without actually loading them you may use the withCount method, which will place a {relation}_count column on your resulting models.

Source