Smart Relationships

Expected behavior

I followed the guide here:

to make a smart relationship. I don’t have a FK in the database, but want to save the ID of an item in another table. I thought smart fields could do this as a “virtual” relationship.

Actual behavior

When I try and save the record with the item selected in the smart relationship, there is a put request generated to a /relationships/field_name endpoint that doesn’t exist.

Failure Logs

forestadmin | PUT /forest/city/C58AD591-D364-4F34-974C-2F1D60B44667/relationships/pageImage 404 211 - 1.835 ms


Please provide any relevant information about your setup.

  • Database Dialect: mssql

Hello @Jonathan_Nye !

In order to make this work, you would have to implement routes related to this new relationship (That’s why smart relationships are set to read only by default).

Here is a quick example using Cars and Users models. Users have a field car that should match with the Cars name field.

In case I want to have a smart relationship car_relation, I would need to add :
In forest/users.js:

collection('users', {
  actions: [],
  fields: [{
    field: 'car_relation',
    type: 'String',
    reference: '',
    get: function (user) {
      return{ where: { name: }});
  segments: [],

Then, if you want to be able to create new records with this relation, you need to override the POST route in routes/users.js :

// Create a User with the new relation'/users', permissionMiddlewareCreator.create(), async (request, response, next) => {
  try {
    const requestBody = request.body;
    // if the relation is present
    if( {
      // Find the associated relation
      const relationshipCar = await;
      // Manually update the given body to handle the relation =;
    // Update the record and send it back
    const recordCreator = new RecordCreator(models.users);
    const recordToCreate = await recordCreator.deserialize(requestBody);
    const newRecord = await recordCreator.create(recordToCreate);
    const serializedRecord = await recordCreator.serialize(newRecord);
  } catch (err) {

Finally, if you want to update the record via the same mecanism, you will need to add a relationship routes, in the same routes/users.js file :

router.put('/users/:userId/relationships/car_relation', async (request, response, next) => {
  try {
    // contains the id of the selected car in the UI
    if( {
      // Get all the record needed and update
      const user = await models.users.findByPk(request.params.userId);
      const car = await; =;
  } catch (err) {

Hope this will help :slight_smile:


Thank you so much. This works perfectly!

1 Like