mickhansen / graphql-sequelize

GraphQL & Relay for MySQL & Postgres via Sequelize
MIT License
1.9k stars 172 forks source link

Association fields with the same column name getting overwritten #675

Closed julianwyz closed 5 years ago

julianwyz commented 5 years ago

Package versions:

I've recently run into an unexpected behavior where querying a field in a many-to-many association - when two models have a field that has the same name - causes the column to be clobbered.

This case is a little hard to explain, so I'll try to give an overview of my situation below and the issue should become apparent.

I have three models: Contract, Organization and OrganizationType. They look roughly like this:

Contract

id email
123 hello@example.com

Organization

id name organizationTypeId
456 My Org 1

OrganizationType

id name
1 Admin

I also have a join table between Organizations and Contracts:

OrganizationId ContractId
456 123

Now when I run the following GraphQL query:

query {
  Organization(id: 456) {
    id
    name
    Type {
      id
      name
    }
  }
}

The response is what I would expect:

{
  "data": {
    "Organization": {
      "id": 456,
      "name": "My Org",
      "Type": {
        "id": "1",
        "name": "Admin" <--- Note the OrganizationType
      }
    }
  }
}

But If I attempt to get the same association via the Contracts list query:

query {
  Contracts(limit: 1) {
    id
    Organizations {
      id
      name
      organizationTypeId
      Type {
        name
        id
      }
    }
  }
}

This is what is returned:

{
  "data": {
    "Contracts": [
      {
        "id": 123,
        "Organizations": [
          {
            "id": 456,
            "name": "My Org",
            "organizationTypeId": 1,
            "Type": {
              "name": "My Org", <--- name is from Organization
              "id": 1 <--- ID is the proper OrganizationType ID
            }
          }
        ]
      }
    ]
  }
}

I believe my schema is configured correctly (because when I query the Organization, the type is returned correctly) - but if it helps, this is roughly what I have:

models.Contract._Organizations = models.Contract.belongsToMany(models.Organization, {
  through: models.OrganizationContract
});
models.Organization._OrgType = models.Organization.belongsTo(models.OrganizationType, {
  foreignKey: 'organizationTypeId'
});

...

const contractType = new GraphQLObjectType({
    name: "Contract",
    fields: () => ({
      ...attributeFields(Contract),
     Organizations: {
          type: new GraphQLList(organizationType),
          resolve: resolver(Contract._Organizations)
        }
    })
})

const organizationTypeType = new GraphQLObjectType({
    name: "OrganizationType",
    fields: () => ({
      ...attributeFields(OrganizationType)
    })
})

const organizationType = new GraphQLObjectType({
    name: "Organization",
    fields: () => ({
      ...attributeFields(Organization),
        Type: {
          type: organizationTypeType,
          resolve: resolver(Organization._OrgType)
        }
    })
  })

I believe the issue is because the Organization model and the OrganizationType model both have a field named name. But the SQL that is getting output is correct and as far as I can tell I have setup my schema correctly. Is this a bug? Or am I missing something?

Thanks ahead of time for any guidance

mickhansen commented 5 years ago

Not sure what the issue is here. If you can reproduce the error with a smaller sample (or even better a PR with a failing test) i can look into it.

julianwyz commented 5 years ago

Ok. Good to know this is indeed unexpected and I wasn’t just doing something silly :wink:

I will work on a PR for this.

julianwyz commented 5 years ago

🤦‍♂ I am very sorry for wasting your time - the name was the same on the two fields because that is the way it was in the actual data.

My bad. Thanks again for your help!

mickhansen commented 5 years ago

Haha, hate when stuff like that happens!