Woodshop
Search…
Pre-fill a form with data from a relationship
This example shows you how to implement a smart action form where input fields are pre-filled with data coming from a hasOne relationship. Here a Movie hasOne movieCharacteristic. On the movies collection, we want to implement a smart action to edit the characteristics of a movie.
To do so, a smart action called update-movie-characteristicsis defined with input fields corresponding to the fields of the movieCharacteristic we want to edit. Their value is pre-filled to ensure the user is aware of their current value before editing them.

Requirements

    An admin backend running on forest-express-sequelize

How it works

Directory: /models

This directory contains the movies.js and movie-characteristics.js files where the models are defined.
movies.js
movie-characteristics.js
1
module.exports = (sequelize, DataTypes) => {
2
const { Sequelize } = sequelize;
3
4
const Movies = sequelize.define('movies', {
5
title: {
6
type: DataTypes.STRING,
7
},
8
releaseYear: {
9
type: DataTypes.INTEGER,
10
},
11
rating: {
12
type: DataTypes.INTEGER,
13
},
14
picture: {
15
type: DataTypes.STRING,
16
},
17
academyAward: {
18
type: DataTypes.BOOLEAN,
19
},
20
}, {
21
tableName: 'movies',
22
underscored: true,
23
timestamps: false,
24
schema: process.env.DATABASE_SCHEMA,
25
});
26
27
Movies.associate = (models) => {
28
Movies.hasOne(models.movieCharacteristics, {
29
foreignKey: {
30
name: 'movieIdKey',
31
field: 'movie_id',
32
},
33
as: 'movieCharacteristic',
34
});
35
};
36
37
return Movies;
38
};
39
Copied!
1
module.exports = (sequelize, DataTypes) => {
2
const { Sequelize } = sequelize;
3
4
const MovieCharacteristics = sequelize.define('movieCharacteristics', {
5
language: {
6
type: DataTypes.BOOLEAN,
7
},
8
graphicViolence: {
9
type: DataTypes.BOOLEAN,
10
},
11
nudity: {
12
type: DataTypes.BOOLEAN,
13
},
14
drugs: {
15
type: DataTypes.BOOLEAN,
16
},
17
gore: {
18
type: DataTypes.BOOLEAN,
19
},
20
}, {
21
tableName: 'movie_characteristics',
22
underscored: true,
23
timestamps: false,
24
schema: process.env.DATABASE_SCHEMA,
25
});
26
27
MovieCharacteristics.associate = (models) => {
28
MovieCharacteristics.belongsTo(models.movies, {
29
foreignKey: {
30
name: 'movieIdKey',
31
field: 'movie_id',
32
},
33
as: 'movie',
34
});
35
};
36
37
return MovieCharacteristics;
38
};
39
Copied!

Directory: /forest

This directory contains the movies.js file where the smart action update-movie-characteristics is declared. We use the value method to pre-fill smart action forms.
/forest/programs.js
1
const { collection } = require('forest-express-sequelize');
2
const sequelize = require('sequelize');
3
const models = require('../models');
4
5
collection('movies', {
6
actions: [{
7
name: 'update movie characteristics',
8
type: 'single',
9
fields: [{
10
field: 'language',
11
type: 'Boolean',
12
description: 'update the checkbox',
13
}, {
14
field: 'gore',
15
type: 'Boolean',
16
description: 'update the checkbox',
17
}, {
18
field: 'drugs',
19
type: 'Boolean',
20
description: 'update the checkbox',
21
}, {
22
field: 'graphicViolence',
23
type: 'Boolean',
24
description: 'update the checkbox',
25
}, {
26
field: 'nudity',
27
type: 'Boolean',
28
description: 'update the checkbox',
29
}],
30
values: async (context) => {
31
console.log(context);
32
// sequelize query to fetch the movie record
33
// do not forget to include the movie characteristics model
34
const movie = await models.movies.findByPk(context.id, {
35
include: [{
36
model: models.movieCharacteristics,
37
as: 'movieCharacteristic'
38
}]
39
});
40
// Forest Admin will match all of the form fields that have the same name
41
// as your movie characteristics fields and pre-fill them
42
return movie.movieCharacteristic;
43
},
44
}],
45
});
46
Copied!
Don't forget to make the values method asynchronous as you will need to await the resolve of the promise fetching the movie record.
Last modified 1yr ago