Add many existing records at the same time (hasMany-belongsTo relationship)
This example shows how to associate multiple existing records at once to a record using a simple smart action.
Last updated
This example shows how to associate multiple existing records at once to a record using a simple smart action.
Last updated
const { collection } = require('forest-express-sequelize');
const { companies } = require('../models');
collection('organizations', {
actions: [{
name: 'Associate companies',
type: 'single',
fields: [
{
field: 'search',
type: 'String',
reference: 'companies',
isRequired: false,
hook: 'onSearchChange',
},
{
field: 'selection',
type: ['String'],
isReadOnly: true,
isRequired: true,
hook: 'onSelectionChange',
},
],
hooks: {
change: {
onSearchChange: async ({ fields }) => {
// Retrieve fields
const selection = fields.find((field) => field.field === 'selection');
const search = fields.find((field) => field.field === 'search');
if(!!search.value){
// Retrieve the company name by querying the DB
const { name: searchValue } = (await companies.findByPk(search.value)) || {};
// Adding company names when searching matches
if (searchValue) {
const allAddedValues = [...(selection.previousValue || []), searchValue]; // ...() spread the array
// Unique array values using a set
selection.value = [...new Set(allAddedValues)];
// Allow user to interact with selection field
selection.isReadOnly = false;
// Reset search value
search.value = '';
}
}
return fields;
},
onSelectionChange: async ({ fields }) => {
// This hooks is needed to allow company removal from selection
const selectionField = fields.find((field) => field.field === "selection");
// Enable or disable user interactions
if (selectionField.value?.length > 0) {
selectionField.isReadOnly = false;
} else {
selectionField.isReadOnly = true;
}
return fields;
},
},
},
}],
fields: [],
segments: [],
});const express = require('express');
const { PermissionMiddlewareCreator } = require('forest-express-sequelize');
const { companies, objectMapping: { Op } } = require('../models');
const router = express.Router();
const permissionMiddlewareCreator = new PermissionMiddlewareCreator('organizations');
// Associate companies smart action route
router.post('/actions/associate-companies', permissionMiddlewareCreator.smartAction(), async (req, res) => {
const { body: { data: { attributes } } } = req;
const companyNames = attributes.values['selection'];
// Retrieve all companies ids using the company names sent by the action form
const companyIds = (await companies.findAll({
where: { name: { [Op.in]: companyNames } },
attributes: ['id']
})).map((company) => company.id);
// Retrieve organization id from the request
const organizationId = attributes.ids[0];
// Update the companies to add the belongsTo association
await companies.update({ organizationId: organizationId }, { where: { id: companyIds }});
// Send success toasted and refresh the related data in the Summary
res.send({
success: 'Companies have been added!',
refresh: { relationships: ['companies'] },
});
});
module.exports = router;