nuwave / nuwave/lighthouse

Limit a queries select to the model's table

Open
#1,214 6 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
PHP
Stars
3.5k
Forks
468
Avg merge
3h 9m
Merged PRs (30d)
2

Description

Describe the bug

I have the following type:

type User @modelClass(class: "App\\Models\\User") {
    id: ID!
    donations(
        type: String = "charge" @where(key: "donations.type")
        status: String = "complete" @where(key: "donations.status")
        teamId: ID @scope(name: "byTeam")
    ): [Donation!]
        @hasMany(type: "connection")
}

User.donations is a hasManyThrough relationship. So in order to limit by teamId an additional join is applied during the scope:

    public function scopeByTeam(Builder $query, int $teamId): Builder
    {
        $table = $this->getTable();

        $query
            ->join('campaigns', "$table.campaign_id", '=', 'campaigns.id')
            ->where('campaigns.team_id', '=', $teamId);

        return $query;
    }

This is where things break. The resulting donations have much of the correct data but the wrong ID. The reason for this is actually pretty simple. By default selects in Laravel are *, which means that all columns including the joined table columns are included. Since the joined table also has an ID column and it comes later in the results the ID of the joined table item is returned instead of the correct table's ID.

Expected behavior/Solution

Since Lighthouse has the model and is building the query, all we should really need to do here is to apply the table to the query select. Something like $query->select("{$model->getTable()}.*").

I don't believe this would cause backwards-incompatibility as the GraphQL object is expecting to only be a single model, anyway. The only scenarios I'm not sure of is how Lighthouse handles sub-models and eager loading.


Environment

Lighthouse Version: 5.9
Laravel Version: 6.x

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the hasManyThrough relationship and the @hasMany(type: "connection") query path described in the issue, then inspect how the model and scopeByTeam join affect the selected columns. The change is done when joined columns no longer overwrite the model's attributes, especially its ID, while the relationship and eager-loading behavior still work.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, laravel, php
Domain
api, backend, database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.