Reference key not displayed in related data

I have contracts and places. A place has many contracts. A contract belongs to a place.

Places.hasMany(models.contracts, {
      foreignKey: {
        name: 'placeIdKey',
        field: 'place_id',
      },
      as: 'contracts',
    });
Contracts.belongsTo(models.places, {
      foreignKey: {
        name: 'placeIdKey',
        field: 'place_id',
      },
      as: 'place',
    });

As you can see in the video below, in the contracts collection table view, everything is displayed without issue. But when I display the place related data “contracts”, most of the time, the place’s contract is not, until I access the contract summary view, the place is gathered, kept in buffer and displayed when I go back to the table view.

I immediately thought about this past issue

but this time, the relationships aliases from a collection to another are so short that I don’t think I reached a postgreSQL limitation.

Hi @JeremyV :wave: to order to reproduce, can you explain me a little bit what kind of type is the reference field? smart field or not?
Have you any errors logs on your server or on your browser?
Can you share with us the anonymised result of the http call when you click on the related data compte client section?

The places reference field is its displayName:

it is just a plain text field, not a smart field.

I do not not have any error in my data gathering:

in the data I do not get the place related information

Hey @JeremyV,

Could you also share your forest-express-sequelize version of your project?
I can see a few recent release about this and I’m currently not able to reproduce this issue.

Thanks in advance.

“forest-express-sequelize”: “^7.6.3”,

Have you override the /forest/places/:placesId/relationships/contracts routes?
When I try to reproduce your exemple, I have the include property inside the response payload
image
who contains all the information to display the relation.

Yes I did:

In the GET route I need to enrich my record to add the userEmail

router.get('/places/:place_id/relationships/contracts', (request, response, next) => {
  const place_id = request.params.place_id;
  const limit = parseInt(request.query.page.size, 10) || 20;
  const offset = (parseInt(request.query.page.number, 10) - 1) * limit;
  const recordsGetter = new RecordsGetter(models.contracts);
  const where = { place_id };

  // find the buildingEquipments for the requested page and page size
  const findAll = models.contracts.findAll({
    where,
    offset,
    limit,
  });

  // count all buildingEquipments for pagination
  const count = models.contracts.count({ where });

  // resolve the two promises and serialize the response
  Promise.all([findAll, count])
    .then(([contractsFound, contractsCount]) => {
      const recordsWithUser = contractsFound.map(record => {
        record.userEmail = request.user.email;
        return record;
      });
      return recordsGetter.serialize(recordsWithUser, { count: contractsCount });
    })
    .then((recordsSerialized) => response.send(recordsSerialized))
    .catch(next);
});

In the POST route I had to do that in order to prevent a “permission denied” error when I create a contract within a place

router.post('/places/:place_id/relationships/contracts', (req, res, next) => {
  res.sendStatus(200);
});

Hi @JeremyV :wave: If i’m not mistaking it missing an include related to places inside your findAll call

const findAll = models.contracts.findAll({
    where,
    offset,
    limit,
    includes: [{
      model: models.places
    }],
  });

Try to do something like that :pray: and let me know.

Hi @Arnaud_Moncel,

Sorry, despite this code addition, no change whatsoever. :frowning:

I don’t understand why is not working :thinking: i reproduced your issue and when i add the missing include it’s working.
Have you got any errors log when you add this includes?
Can you share with us the anonymized log of one record with includes?

I don’t have any errors

GET /forest/places/185/relationships/contracts?timezone=Europe%2FParis&fields%5Bcontracts%5D=nom%20complet%2CdisplayName%2Crole%2CDate%20derniere%20connexion%20%2Cplace&fields%5Bplace%5D=displayName&page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=-id 200 26431 - 2266.356 ms

I even tried with this :

 includes: [{
      model: models.places,
      as: 'place'
    }],

What I forgot to mention is that I duplicated the places collection as integrations, so the contracts collection has 2 relationships:

 Contracts.belongsTo(models.places, {
      foreignKey: {
        name: 'placeIdKey',
        field: 'place_id',
      },
      as: 'place',
    });
    Contracts.belongsTo(models.integrations, {
      foreignKey: {
        name: 'placeIdKey',
        field: 'place_id',
      },
      as: 'integration',
    });

so I tried with

includes: [{
      model: models.places
    }, {
      model: models.integrations
    }],

But I still am in the /places/:place_id/relationships/contracts route so i don’t think this is related.

Log is not different from before

I wanted to talk about a log from your server before serialization like console.log(contractsFound) with the model included.

Here’s one record in the contractsFound array :

  contracts {
    dataValues: {
      id: '441',
      displayName: '9212676 ( N°Lot 0004 - Bâtiment 01,  N°Lot 0008 - Bâtiment 01)',
      amount: '52065',
      createdAt: 2021-03-10T16:14:17.181Z,
      updatedAt: 2021-03-10T16:14:17.181Z,
      parcelSergicId: null,
      sergicUpdateTime: null,
      customerReferenceNumber: '9212676',
      customerKey: null,
      invitedCount: 0,
      sergicVipCode: null,
      sergicVipLabel: null,
      reportAccountEntryAmount: '0',
      reportAccountEntryOperationDate: null,
      deletedAt: null,
      coownerAmount: '52065',
      pendingAmount: 0,
      dueDate: null,
      occupant: null,
      identityIdKey: null,
      placeIdKey: '157'
    },

I don’t understand why is not working with the include.
The issue comes from here, you need to have the place included in your record.
What is the version of Sequelize?

“sequelize”: “~5.15.1”

Do I have to upgrade to v6 ?

Hi @JeremyV :wave: I’m afraid, i made a mistake when i suggest you to add include.

the real code is

const findAll = models.contracts.findAll({
    where,
    offset,
    limit,
    include: [{
      model: models.places,
      as: 'place',
    }],
  });

It is include not includeS!
I’m really sorry about that.
It should work now.
Let me know.

@Arnaud_Moncel it works indeed ! Thank you.

1 Like