For eager loaded relationships, you can do:
->with([
'profile' => function ($query) {
$query->select('colName1', 'colName2');
}
])
For the main query (users), you can just directly chain ->select(...) directly.
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I have 3 tables
Users id
Games id status
Collections game_id user_id
I have the relationships in my models set up as such:
User::hasMany(Collection)
Collection::belongsTo(Game)
Game::hasMany(Collection)
I'm trying to get all the users along with their profiles as well as the collections and games they own where the status of the game is not denied. To do all of that, I'm using the following code
User::with(['profile'])->with('collections.game')
->whereHas('collections', function (Builder $query) {
return $query->whereHas('game', function (Builder $query) {
return $query->where('status', '<>', 'denied');
});
})
->paginate(10)
That works great. It's giving me pretty much what I want. The problem is that it's actually giving me more than what I want -- it's giving me all columns in both the user and profile tables (which could include full name and physical address). Under normal circumstances, that wouldn't be a problem. All the extra data would be lost after the blade template was parsed and returned to the browser. In my case, however, I'm trying to learn InertiaJS with react and because Inertia is retrieving the dataset via XHR, all of that data is visible to the end-user if they felt curious and wanted to check out the network traffic.
How can I get it so that it returns only particular columns from those two tables? I've tried adding a second parameter to the ::with() call as a closure where I could modify the builder but that didn't seem to work (not to say I was doing it the right way). Is there a way I can do it with the model itself? Or am I going to have to go straight to the Db facade and build out the query that way with the requisite joins?
christoph
@_christoph You have two errors. One of which is because I forgot to specify something important.
$query instance of an eager load closure is not an Illuminate\Database\Eloquent\Builder instance (that's why they don't explicitly type it in the docs).id column and the foreign column related to the given relation you're trying to eager load, so the framework can properly match the data. So in your case, you probably have to select user_id as well as the columns you want.As for the toSql() part where you're saying it's building subqueries, it's because of the whereHas calls (not the eager loading which is treated separately in other queries). It uses subqueries to avoid multiple issues that would affect the developers "quality of life", such as column names ambiguity and "SELECT list is not in GROUP BY clause" errors or duplicate entries returned that would happen if they would use joins.
Please or to participate in this conversation.