Smart hasMany relationship in mongoDB
Context: As a user I want to display records that have a belongsTo relationship to another record as related data of this record.
Parent collection: user
Child collection: visualisation

Models definition

models/user.js
1
// This model was generated by Lumber. However, you remain in control of your models.
2
// Learn how here: <https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models>
3
const mongoose = require('mongoose');
4
5
// This section contains the properties of your model, mapped to your collection's properties.
6
// Learn more here: <https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model>
7
const schema = mongoose.Schema({
8
'avatar_link': String,
9
'client': { type: mongoose.Schema.Types.ObjectId, ref: 'client' },
10
'date_added': Date,
11
'email': String,
12
'first_name': String,
13
'last_name': String,
14
'user_type': String,
15
}, {
16
timestamps: false,
17
});
18
19
module.exports = mongoose.model('user', schema, 'user');
Copied!
models/visualisation.js
1
// This model was generated by Lumber. However, you remain in control of your models.
2
// Learn how here: <https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models>
3
const mongoose = require('mongoose');
4
5
// This section contains the properties of your model, mapped to your collection's properties.
6
// Learn more here: <https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model>
7
const schema = mongoose.Schema({
8
'description': String,
9
'name': String,
10
'user': { type: mongoose.Schema.Types.ObjectId, ref: 'user' },
11
'visualisation_type': String,
12
}, {
13
timestamps: false,
14
});
15
16
module.exports = mongoose.model('visualisation', schema, 'visualisation');
Copied!

Declaration of the relationship

As the relationship that is not present in your database structure, declare it at the level of the forest folder.
forest/user.js
1
const { collection } = require('forest-express-mongoose');
2
const { customFieldsStyles } = require('../style/fields-style.js');
3
4
// This file allows you to add to your Forest UI:
5
// - Smart actions: <https://docs.forestadmin.com/documentation/reference-guide/actions/create-and-manage-smart-actions>
6
// - Smart fields: <https://docs.forestadmin.com/documentation/reference-guide/fields/create-and-manage-smart-fields>
7
// - Smart relationships: <https://docs.forestadmin.com/documentation/reference-guide/relationships/create-a-smart-relationship>
8
// - Smart segments: <https://docs.forestadmin.com/documentation/reference-guide/segments/smart-segments>
9
collection('user', {
10
actions: [],
11
fields: [
12
{
13
field: 'visualisations',
14
type: ['String'],
15
reference: 'visualisation._id',
16
},
17
],
18
segments: [],
19
});
Copied!

Implementation of the get route for the relationship

The route to get the related visualisations when you are on a user page needs to be implemented in the routes folder.
routes/user.js
1
const express = require('express');
2
const { PermissionMiddlewareCreator, RecordSerializer } = require('forest-express-mongoose');
3
const mongoose = require('mongoose');
4
const { visualisation } = require('../models');
5
6
const router = express.Router();
7
const permissionMiddlewareCreator = new PermissionMiddlewareCreator('user');
8
9
...
10
11
router.get('/user/:recordId/relationships/visualisations', permissionMiddlewareCreator.details(), async (req, res, next) => {
12
const limit = parseInt(req.query.page.size) || 10;
13
const offset = (parseInt(req.query.page.number) - 1) * limit;
14
const userObjectId = mongoose.Types.ObjectId(req.params.recordId);
15
const visualisationSerializer = new RecordSerializer({ modelName: 'visualisation' });
16
const count = await visualisation.countDocuments({ user: userObjectId });
17
const data = await visualisation.find({ user: userObjectId }, null, { skip: offset, limit });
18
const dataSerialized = await visualisationSerializer.serialize(data, { count });
19
res.send(dataSerialized);
20
});
21
22
module.exports = router;j
Copied!