1
votes

I'm setting up a GraphQL Apollo Server, and want to define a resolver for an object type that has an element containing an array of data based on a many to many relationship.

I have a Measurement object that is associated to an Activity object with a many to many relationship:

Measurement.belongsToMany(Activity, {
    as: 'activity',
    through: 'activity_measurement_entries',
    underscored: true
});
Activity.belongsToMany(Measurement, {
    as: 'measurements',
    through: 'activity_measurement_entries',
    underscored: true
});

A resolver query works fine for the getActivities query when Measurement is included directly in the query like this:

getActivities: async (parent, args, { models }) => {
    const activities = await models.Activity.findAll({
        include: [{
            model: models.Measurement,
            as: 'measurements',
        }],
    });
    return activities;
},

An activity_measurement table is generated automatically through Sequelize which contains activity_id and measurement_id.

I would like to define a resolver for the measurements field on Activity like below, but I'm not sure how to structure the where clause and what is passed in the parent parameter with the many to many relationship table in the middle (assume a similar getActivities query is used to get all Activities and the associated measurements but no input parameter to the query):

Activity: {
    measurements: (parent, args, { models }) => models.Measurement.findAll({
      where: {
        ????
      },
    }),
},

For a query that attempts to get all the Activities when the Activity type is defined like this:

getActivities: async (parent, args, { models }) => 
    models.ActivityEntry.findAll()

If there is no where clause in the resolver for the measurements field of the Activity type then every measurement is returned under every Activity (instead of just the measurements associated through the activity_measurement table).

I am trying to figure out how to get only the measurements associated with the Activity to be returned when using the separate Activity type definition with a measurements element.

1

1 Answers

0
votes

The parent value that's passed to the resolver reflects the value that was returned in the parent field's resolver. In this case, for the measurements field, the parent field is getActivities. You're returning an array of Activity model instances in getActivities, so the parent value passed to the measurements field resolver will also be an instance of your Activity model.

That means you can do something like:

Activity: {
  measurements: (activity, args, { models }) => activity.getMeasurements(),
},