Search code examples
laraveleloquentlaravel-6

Laravel error using with() method in Eloquent


I'm trying to call using with() method in Laravel Eloquent ORM, but getting the following error.

Argument 1 passed to App\Http\Controllers\DashboardController::App\Http\Controllers\{closure}() must be an instance of Illuminate\Database\Eloquent\Builder, instance of Illuminate\Database\Eloquent\Relations\HasMany given

I'm using the latest version of Laravel 6. Any ideas what might have caused this?

Controller

class DashboardController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api');
    }

    public function formIndex(Request $request)
    {
        $id = auth()->user()->id;
        $item = Groupe::find($id)->with(
            [
                'etudiants' => function (Builder $query) {
                    $query->select('id');
                }
            ]
        )->first();

        return $item;
    }
}

Model

class Groupe extends Authenticatable implements JWTSubject
{
    public function etudiants()
    {
        return $this->hasMany('App\Etudiant');
    }
}

Solution

  • The error comes from the type hint you put on the $query variable, as the error message said the object that gets passed in there is a relationship not a raw Query Builder. Just remove the type hint. Also ::find() executes a query, so you're be executing 2 queries, use the query below instead

    Groupe::where('id', $id)->with(['etudiants' => function ($query) {
            $query->select('id');
        }])->first();
    

    Additionally, you don't need to use the callback syntax to only eager load certain columns, the callback syntax is for putting contraints on which records get returned. Try this instead.

    Groupe::where('id', $id)->with('etudiants:id,name,email')->first();