Field representing related object not populating

We have a strange issue where some relationship data is not populated within a table until you actually open the record and then navigate back to the table view again. This seems to happen only when the objects are accessed as relations of a third object.

This might be hard to track down and look at through the support forum but I’ll try to explain as best I can.

Our data has the following structure:
Course - hasMany -> Certificates - hasOne -> User

When we open a single Course and select “Certificates” from Related data, the field “Name” which represents the User object relation is empty.
If you click on the Certificate object row you can see the correct User representation in the single view, and if you navigate back the user representation is once again visible.
Screenshots below.

Is this linked to the structure of data loading in Forest admin or can we do something about this in our own implementation?

==== Screens ====

Table view, Name / User empty

Opened first Certificate object row

Navigate back to table view, User filled

Hi @svensson-david,

Thank you for the very clear issue explanation.

Is the “Completeds” relationship a Smart Relationship?

Hello!
Yes, the Completeds and courses are related through a join model so it uses a smart relationship to get it working. Unfortunately the naming is a bit confusing currently but the database table of Completeds is called course_completions.

Pasting the related code from routes/courses.js below:

router.get('/courses/:recordId/relationships/course_completions', (request, response, next) => {
  const courseId = request.params.recordId
  const limit = parseInt(request.query.page.size, 10) || 20
  const offset = (parseInt(request.query.page.number, 10) - 1) * limit
  const recordsGetter = new RecordsGetter(course_completions)
  const include = [{
    model: course_versions,
    as: 'course_versions',
    where: { course_id: courseId }
  }]

  // Prepare promises for users and user count
  const findAll = course_completions.findAll({
    include,
    offset,
    limit
  })
  const count = course_completions.count({ include })

  // resolve the two promises and serialize the response
  Promise.all([findAll, count])
    .then(([courseCompletionsFound, courseCompletionsCount]) =>
      recordsGetter.serialize(courseCompletionsFound, { count: courseCompletionsCount }))
    .then((recordsSerialized) => response.send(recordsSerialized))
    .catch(next)
})

Ok great,

So the display issue is certainly related to the Smart Relationship route (/courses/:recordId/relationships/course_completions) implementation.

If the findAll result does not contain the joined user for each course_completion,
you’ll need to adapt it.
If the issue is at the serialisation level, it needs to be adapted too.

Anyway, the recordsSerialized json response must contain the user values to let the table view fill in those users on first display and make the issue you described above vanish.

Does it help?

Hello again!
Thanks, that made it clear and I got it working.

I assumed that the record getter would handle the inclusions for me since the relationships are defined on the model. Will keep that in mind.

Have a nice weekend!

1 Like