Get relation changes in afterSave or beforeSave

Heys guys,

i have a Class “Department” with a relation “users” and an attribute userCount".

I want to set the userCount according to the count of the relation “users”. In beforeSave the changes to the relation aren’t applied and in the afterSave i will get a endless loop because I am saving the same object again.

Is there a trick to do that?

Thanks!

Parse.Cloud.afterSave('_User', async (request) => {
  const customClass = new Parse.Query('customClass');
  const userCount = new Parse.Query('userCount');

  const query = customClass.equalTo('objectId', customClassId);
  const customClassObject = await query.first()

  const customClassUsers= customClassObject.relation('users').query()
  const countUsers = await customClassUsers.count()

  const customClassCount = customClassObject.relation('userCount').add(countUsers)
}

hmm maybe something like that.
afterSave trigger should trigger only once when object is saved.
countUsers should be an object but .count() returning number, i don’t know how your schema looks like but maybe this will give you any clue.

I’m sorry, i didnt describe my problem very well… There is no relation or Class userCount.

I have one Class “Department” with a relation called “users” and an attribute “userCount”. And i want to sync the count of the relation to this field. So I don’t have to fetch the relation to know the count of the users in the frontend.

Parse.Cloud.afterSave('_User', async (request) => {
  const Department = Parse.Object.extend('Department');
  const departmentQuery = new Parse.Query(Department);
  const query = departmentQuery.equalTo('objectId', id); //get department with specified objectId
  const departmentObject = await query.first();
  const usersRelation = departmentObject.relation('users').query();
  query.first().then(async (res) => {
    const queryRelation = await res.relation('users').query().count(); //query users relation inside Department and retrive count of records
    departmentObject.set('userCount', queryRelation); // add this value to userCount
  });
});

i think this should work

Is the afterSave for the User triggered when I add a user to a relation of the department?

I had it like this:

Parse.Cloud.afterSave('Department', async ({ object }) => {
  const count = await object.relation('users').query().count({ useMasterKey: true });
  object.set('userCount', count);
  return object.save(null, { useMasterKey: true });
});

And this is obviously an endless loop…

The problem with count is that it runs over every single object in the database, which can be inefficient. See avoiding count operations.

Instead, it would be more efficient to track the changes by using operation: object.op('users').

Parse.Cloud.afterSave('Department', async ({ object }) => {
  const op = object.op('users');
  if (op) {
    const changeCount = op.relationsToAdd.length - op.relationsToRemove.length;
    object.increment('userCount', changeCount);
    return object.save(null, { useMasterKey: true });
  }
}, {
  skipWithMasterKey: true
});
1 Like

Thanks! Helped a lot. <3