mickhansen / graphql-sequelize

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

How do associations work? #659

Closed mschipperheyn closed 5 years ago

mschipperheyn commented 5 years ago

I'm trying to follow the example, but associations are not picked up.

export default function UserModel(seq, DataTypes) {
    class User extends Sequelize.Model {
        static init(sequelize, DataTypes) {
            return super.init(
                {
                    id: {
                        type: DataTypes.UUID,
                        defaultValue: DataTypes.UUIDV4,
                        primaryKey: true,
                        lowercase: true,
                    },
                    searchText: {
                        type: DataTypes.STRING(255),
                    },
                    username: {
                        type: DataTypes.STRING(255),
                    },
                    email: {
                        type: DataTypes.STRING(255),
                        unique: true,
                        required: true,
                    },
                },
                {
                    tableName: 'Users',
                    indexes: [
                        {
                            type: 'FULLTEXT',
                            name: 'searchText',
                            fields: ['searchText'],
                        },
                    ],
                    sequelize,
                },
            );
        }

        static beforeSave = item => {
            item.searchText = `${item.username || ''} ${item.email || ''}`;
            return item;
        };

        static addInclude = () => [];

        static associate = models => {
            User.hasMany(models.Pet, {
                foreignKey: 'petId',
                require: false,
                onDelete: 'cascade',
                as: 'pets',
            });
        };

        toJSON() {
            const values = { ...this.get() };

            values.pets = values.pets
                ? values.pets.map(pet => pet.toJSON())
                : [];

            return values;
        }
    }

    User.init(seq, DataTypes);

    return User;
}
export default function PetModel(seq, DataTypes) {
    class Pet extends Sequelize.Model {
        static init(sequelize, DataTypes) {
            return super.init(
                {
                    id: {
                        type: DataTypes.UUID,
                        defaultValue: DataTypes.UUIDV4,
                        primaryKey: true,
                        lowercase: true,
                    },
                    name: {
                        type: DataTypes.STRING(255),
                    },
                },
                {
                    tableName: 'Pets',
                    sequelize,
                },
            );
        }

        static associate = models => {
            Pet.belongsTo(models.User, {
                foreignKey: 'petId',
            });
        };
    }

    Pet.init(seq, DataTypes);

    return Pet;
}
        type Pet implements Node {
        id: ID!
        name: String
        createdAt: DateTime!
        updatedAt: DateTime
    }
        type User implements Node & Searchable {
        id: ID!
        username: String
        email: String!
        searchText: String
        pets: [Pet]
        createdAt: DateTime!
        updatedAt: DateTime
    }
users: resolver(User),

When I look up

query{
  user{
       username
       pets { 
             name
       }
   }  
}

no pet related query is executed. pets is an empty array. I was assuming I could use a string based schema definition like in the example repo and didn't implement the manual schema definition like on the homepage. (I expect graphql-sequelize to figure out the associations for me).

bullsei commented 5 years ago

as far as i know associations work only with passing in a sequelize association. its not enough to only associate via graphql fields Like here in Line 7 https://github.com/mickhansen/graphql-sequelize/blob/master/examples/graphql-yoga/src/models/User.js or another example here https://github.com/brianschardt/node_graphql_apollo_template/blob/master/src/graphql/user/user.map.ts

mschipperheyn commented 5 years ago

@bullsei Yes, did that of course. Sorry, my code example was incomplete: I will adjust the original post

mschipperheyn commented 5 years ago

So, it turns out my code was incomplete. I needed to add a type primitive as a root resolver.

                User: {
            pets: (parent, args, context, info) => {
                return parent.getPets();
            },
        },
AxelPariss commented 3 years ago

So, it turns out my code was incomplete. I needed to add a type primitive as a root resolver.

                User: {
          pets: (parent, args, context, info) => {
              return parent.getPets();
          },
      },

Thanks a lot! That works perfect for me! 🙌