Woodshop for old agent generation
Try the new agent generation
  • What is woodshop
  • How to's
    • Smart Relationship
      • GetIdsFromRequest
    • Smart views
      • Display a calendar view
      • Create a custom tinder-like validation view
      • Create a custom moderation view
      • Create a dynamic calendar view for an event-booking use case
    • Configure environment variables
      • NodeJS/Express projects
    • Elasticsearch Integration
      • Interact with your Elasticsearch data
      • Elasticsearch service/utils
      • Another example
    • Zendesk Integration
      • Authentication, Filtering & Sorting
      • Display Zendesk tickets
      • Display Zendesk users
      • View tickets related to a user
      • Bonus: Direct link to Zendesk + change priority of a ticket
    • Dwolla integration
      • Display Dwolla customers
      • Display Dwolla funding sources
      • Display Dwolla transfers
      • Link users and Dwolla customers
      • Dwolla service
    • Make filters case insensitive
    • Use Azure Table Storage
    • Create multiple line charts
    • Create Charts with AWS Redshift
    • View soft-deleted records
    • Send Smart Action notifications to Slack
    • Authenticate a Forest Admin API against an OAuth protected API Backend
    • Translate your project into TypeScript
      • V8
        • Migrate Mongoose files
        • Migrate Sequelize files
      • v7
        • Migrate Mongoose files
        • Migrate Sequelize files
      • v6
    • Geocode an address with Algolia
    • Display/edit a nested document
    • Send an SMS with Zapier
    • Hash a password with bcrypt
    • Display a customized response
    • Search on a smart field with two joints
    • Override the count route
    • Make a field readOnly with Sequelize
    • Hubspot integration
      • Create a Hubspot company
      • Display Hubspot companies
    • Impersonate a user
    • Import data from a CSV file
    • Import data from a JSON file
    • Load smart fields using hook
    • Pre-fill a form with data from a relationship
    • Re-use a smart field logic
    • Link to record info in a smart view
    • Display data in html format
    • Upload files to AWS S3
    • Display AWS S3 files from signed URLs
    • Prevent record update
    • Display, search and update attributes from a JSON field
    • Add many existing records at the same time (hasMany-belongsTo relationship)
    • Track users’ logs with morgan
    • Search on relationship fields by default
    • Export related data as CSV
    • Run automated tests
  • Forest Admin Documentation
Powered by GitBook
On this page
  • Requirements
  • How it works
  • Directory: /models
  • Directory: /forest

Was this helpful?

  1. How to's

Pre-fill a form with data from a relationship

PreviousLoad smart fields using hookNextRe-use a smart field logic

Last updated 4 years ago

Was this helpful?

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.

module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;

  const Movies = sequelize.define('movies', {
    title: {
      type: DataTypes.STRING,
    },
    releaseYear: {
      type: DataTypes.INTEGER,
    },
    rating: {
      type: DataTypes.INTEGER,
    },
    picture: {
      type: DataTypes.STRING,
    },
    academyAward: {
      type: DataTypes.BOOLEAN,
    },
  }, {
    tableName: 'movies',
    underscored: true,
    timestamps: false,
    schema: process.env.DATABASE_SCHEMA,
  });

  Movies.associate = (models) => {
    Movies.hasOne(models.movieCharacteristics, {
      foreignKey: {
        name: 'movieIdKey',
        field: 'movie_id',
      },
      as: 'movieCharacteristic',
    });
  };

  return Movies;
};
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  
  const MovieCharacteristics = sequelize.define('movieCharacteristics', {
    language: {
      type: DataTypes.BOOLEAN,
    },
    graphicViolence: {
      type: DataTypes.BOOLEAN,
    },
    nudity: {
      type: DataTypes.BOOLEAN,
    },
    drugs: {
      type: DataTypes.BOOLEAN,
    },
    gore: {
      type: DataTypes.BOOLEAN,
    },
  }, {
    tableName: 'movie_characteristics',
    underscored: true,
    timestamps: false,
    schema: process.env.DATABASE_SCHEMA,
  });

  MovieCharacteristics.associate = (models) => {
    MovieCharacteristics.belongsTo(models.movies, {
      foreignKey: {
        name: 'movieIdKey',
        field: 'movie_id',
      },
      as: 'movie',
    });
  };

  return MovieCharacteristics;
};

Directory: /forest

/forest/programs.js
const { collection } = require('forest-express-sequelize');
const sequelize = require('sequelize');
const models = require('../models');

collection('movies', {
  actions: [{
    name: 'update movie characteristics',
    type: 'single',
    fields: [{
      field: 'language',
      type: 'Boolean',
      description: 'update the checkbox',
    }, {
      field: 'gore',
      type: 'Boolean',
      description: 'update the checkbox',
    }, {
      field: 'drugs',
      type: 'Boolean',
      description: 'update the checkbox',
    }, {
      field: 'graphicViolence',
      type: 'Boolean',
      description: 'update the checkbox',
    }, {
      field: 'nudity',
      type: 'Boolean',
      description: 'update the checkbox',
    }],
    values: async (context) => {
      console.log(context);
      // sequelize query to fetch the movie record 
      // do not forget to include the movie characteristics model
      const movie = await models.movies.findByPk(context.id, {
          include: [{ 
              model: models.movieCharacteristics,
              as: 'movieCharacteristic' 
          }] 
      });
      // Forest Admin will match all of the form fields that have the same name 
      // as your movie characteristics fields and pre-fill them
      return movie.movieCharacteristic;
    },
  }],
});

Don't forget to make the values method asynchronous as you will need to await the resolve of the promise fetching the movie record.

This directory contains the movies.js file where the smart action update-movie-characteristics is declared. We use the to pre-fill smart action forms.

value method