shaedrich
shaedrich

Reputation: 5735

Improve eager loading with multiple relationships of the same type

I have the following model:

class Message extends Model
{
    public function sender(): HasOne
    {
        return $this->hasOne(User::class, 'sender_id', 'id');
    }

    public function receiver(): HasOne
    {
        return $this->hasOne(User::class, 'receiver_id', 'id');
    }
}

When I do Message::with(['sender', 'receiver'])->all(), eager loading executes the following queries:

SELECT * FROM messages
SELECT * FROM users IN(1, 3, 5)
SELECT * FROM users IN(3, 5, 7)

That's almost the least redundant way possbile. But it still loads user 3 and user five two times. Is there a way to further improve this using eloquent and eager loading?

Upvotes: 1

Views: 671

Answers (2)

Koushik Balo
Koushik Balo

Reputation: 97

Try these

First replace your foreignKey and localKey.

class Message extends Model

{
    public function sender(): HasOne
    {
        return $this->hasOne(User::class, 'sender_id', 'id');
    }

    public function receiver(): HasOne
    {
        return $this->hasOne(User::class, 'receiver_id', 'id');
    }
}

And then use this model query

return Message::query()->with(['sender', 'receiver'])->get()

Upvotes: 0

N69S
N69S

Reputation: 17206

No, not really.

The example you provided is an exception, nothing tells that any user will be present in both sender and receiver queries.

You could write some code to change how Eloquent behaves in those case but it's not worth it.

CONS:

  • The case is restricted to two or more relation eager loaded on the same entity.
  • You need to attach the results you removed back to the second query with the right Order it should be in.
  • might cost way more performance in the code than what it saves from the database.

Upvotes: 3

Related Questions