Smart Field with Multiple References

Hey Forest!

Is it possible to make a smart field reference different tables according to some logic like morphs?

For instance: we have fields such as owner_type & owner_id on a transaction record. This type could be “Operator” or “Team” and according to owner_type I want to have a smart field reference either the Teams or the Operators table. Is this doable?

Thank you!

Hi @Arda_Yurdakul

That’s indeed possible.
I looked at your previous posts (Table with No PK) and will suppose you are using forest-express-sequelize

Here is a code sample I wrote based on the information in your post:

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

collection('a_collection_name', {
  fields: [{
    field: 'owner_display_name',
    get: async (record) => {
      if (record.owner_type === 'Operator') {
        const operator = await models.operators.findByPk(record.owner_id);
        return operator.name;
      } else if (record.owner_type === 'Team') {
        const team = await models.teams.findByPk(record.owner_id);
        return team.name;
      } else {
        return null;
      }
    }
  }],
});

Hey @romaing

Thank you for getting back! This is exactly the logic I am using currently but what I’m thinking of is making it a reference field(I mistakenly said smart field instead of smart relationship). So it would be a link to a team or a link to an operator based on the record. Is this possible?

Thank you :smiley:

It is not possible on a single field (the type of the relation is written in the schema, it can’t change between records).

You can create two relationships, but you’ll always have an empty column

Something like this?

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

collection('a_collection_name', {
  fields: [{
    field: 'operator_owner',
    type: 'Number',
    reference: 'operators.id',
    get: async (record) => {
      if (record.owner_type === 'Operator') {
        const operator = await models.operators.findByPk(record.owner_id);
        return operator.name;
      } else {
        return null;
      }
    }
  }, {
    field: 'team_owner',
    type: 'Number',
    reference: 'teams.id',
    get: async (record) => {
      if (record.owner_type === 'Team') {
        const team = await models.teams.findByPk(record.owner_id);
        return team.name;
      } else {
        return null;
      }
    }
  }],

@romaing Yes this seems like the only solution.

Thank you for the answer.