Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

talel's avatar
Level 16

Query builder with() - morphMany()

Hello,

I have a Client model which has a Contacts relationship, the contacts relationship is a morphMany relationship.

When trying to return only one contact and specific columns from the contacts relationship with the with() method I get back an empty collection.

If I remove the query builder and keep just the name of the relationship as the argument in the with() method I get all the contacts and columns for the contact of that client.

This is the query:

         Client::query()
            ->filter(request()->only(['search']))
            ->select('id', 'name', 'client_status')
            ->with(['contacts' => function ($query) {
                $query->select('email', 'first_name', 'last_name', 'phone_number', 'title')->take(1);
            }])
            ->orderBy('created_at', 'desc')
            ->paginate(10)
            ->withQueryString()

Query log

With specific columns nad limiting to 1

    "query" => "select `email`, `first_name`, `last_name`, `phone_number`, `title` from `contacts` where `contacts`.`contactable_id` in (1000) and `contacts`.`contactable_type` = ? and `contacts`.`deleted_at` is null limit 1 ◀"
    "bindings" => array:1 [▼
      0 => "App\Models\App\Client"
    ]
    "time" => 0.47

Normal with('contacts')

    "query" => "select * from `contacts` where `contacts`.`contactable_id` in (1000) and `contacts`.`contactable_type` = ? and `contacts`.`deleted_at` is null"
    "bindings" => array:1 [▼
      0 => "App\Models\App\Client"
    ]
    "time" => 0.5

When using the query in TablePLus I get the specific columns with only one record as expected.

-Tal

0 likes
3 replies
jbloomstrom's avatar

Why App\Models\App\Client? Should that be App\Models\Client?

You may have an unnecessary import in your model class.

talel's avatar
Level 16

That's just the namespace of that class.

talel's avatar
Level 16

An additional interesting thing is that when dd() inside the with() method, I get the correct results as expected.

->with(['contacts' => function ($query) {
                dd($query->select('email', 'first_name', 'last_name', 'phone_number', 'title')->take(1)->get());
            }])

Please or to participate in this conversation.