I think you should be able to do this...
eager load first, and then filter
$colorid = $request->input('colorid') ?? null;
$sizeid = $request->input('sizeid') ?? null;
$materialid = $request->input('materialid') ?? null;
$results = Choice::with(['color', 'size','material'])
->select('id')
->when(!is_null($colorid), function($query) use ($colorid) {
$query->where('color.id', $colorid);
})->when(!is_null($sizeid), function($query) use ($sizeid) {
$query->where('size.id', $sizeid);
})->when(!is_null($materialid), function($query) use ($materialid) {
$query->where('material.id', $materialid);
})->paginate(20);
I think it should work... alternatively, because you're only selecting the ID from the the choice, you could do probalby do a whereHas
$colorid = $request->input('colorid') ?? null;
$sizeid = $request->input('sizeid') ?? null;
$materialid = $request->input('materialid') ?? null;
$results = Choice::select('id')
->when(!is_null($colorid), function($query) use ($colorid) {
$query->whereHas('color', function(Builder $query) use ($colorid) {
$query->where('id', '=', $colorid);
});
->when(.....)
})->paginate(20);