No model was found for 'forest-medium'

Hello,

Feature(s) impacted

I try to add an organisation with forest admin but i have an error : Organisations creation failed: unexpected error. By the way i can update and add user with out error

Observed behavior

When it use the inspector of chrome i got this one : Error: No model was found for ‘forest-medium’ and no schema handles the type, but don’t understand what’s is happening.

This is a screen shot from the error :

Thanks for helping me

1 Like

Hello @Gauthier_Cornec ! :wave: Welcome to our community :tada: :confetti_ball:

In order to find the culprit, can you share some information about your setup.

  • Which version of forest are you using ? Your project name ?

  • Can you also share your Organisation model definition ?

Do you only encounter the issue in this collection ?

Kind regards,
Morgan

Hello @morganperre,

forest version : forest-cli/2.6.1 darwin-x64 node-v17.7.1
project name: AIA,
Yes it’s only on this collection that i have this error

organiation model :

// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const Organisations = sequelize.define('organisations', {
    name: {
      type: DataTypes.STRING,
    },
    address: {
      type: DataTypes.STRING,
    },
    email: {
      type: DataTypes.STRING,
    },
  }, {
    tableName: 'organisations',
    timestamps: false,
  });

  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  Organisations.associate = (models) => {
    Organisations.belongsToMany(models.medias, {
      through: 'mediasOrganisations',
      foreignKey: 'organisationsId',
      otherKey: 'mediasId',
      as: 'mediasThroughMediasOrganisations',
    });
    Organisations.hasMany(models.playlists, {
      foreignKey: {
        name: 'organisationIdKey',
        field: 'organisationId',
      },
      as: 'playlists',
    });
    Organisations.hasMany(models.users, {
      foreignKey: {
        name: 'organisationIdKey',
        field: 'organisationId',
      },
      as: 'users',
    });
  };

  return Organisations;
};

Kind regards,
Gauthier

Hello again,

I see that you use the forest-express-sequelize v.8.4.8. Looking at the stack log the issue is super wierd.

  • Can you look at the Related data tab ? I’m wondering if something can be broken there.

  • Do you have any fields name medium in other models ?

  • Do you only encounter the issue in development ?

Thank for your answers. :pray:

Kind regards,
Morgan

I look at every Related Data tab and cannot see something strange, i share you the related table maybe you see somethings :

  MediasOrganisations.belongsTo(models.organisations, {
      foreignKey: {
        name: 'organisationsIdKey',
        field: 'organisationsId',
      },
      as: 'organisations',
    });
  };
 Playlists.associate = (models) => {
    Playlists.belongsTo(models.organisations, {
      foreignKey: {
        name: 'organisationIdKey',
        field: 'organisationId',
      },
      as: 'organisation',
    });
  Users.associate = (models) => {
    Users.belongsTo(models.organisations, {
      foreignKey: {
        name: 'organisationIdKey',
        field: 'organisationId',
      },
      as: 'organisation',
    });

I search and actually i got nothing with name medium inside any files.
I try into production mode and i’ve got the same error with forest-medium.

Ok, I just see one little issue. You should use belongsToMany in the following definition for M-N relationship.

I guess the other relations are One-to-Many, I don’t see any issue. Even if sequelize properly handle the naming convention by default. So the following code should give the same comportement.

Playlists.belongsTo(models.organisations);
...
Users.belongsTo(models.organisations);
...
// I personally prefer this usage of through to properly handle the M-N relationship
// You shouldn't have to worry about MediasOrganisations as it been generated by sequelize
Medias.belongsToMany(
  models.organisations,
  { through: 'mediasOrganisations' }
);

Side note: Also using through is the way to go. It will create the junction table automatically with only two columns: organisationsId and mediasId . A composite unique key will be established on these two columns.

Let me know if using the right
Kind regards,
Morgan

Hello @morganperre, I change belongsTo into belongsToMany and i run it without error. Unfortunately i still have the same error with forest-medium when i want to add an organisation

Hello @Gauthier_Cornec,

I’m gonna try to reproduce it locally. I’ll come back to you as soon as possible. :pray:

  • Can you share your .forestadmin-schema.json please ?

  • Do you use Smart field on the Organisation collection ?

Kind regards,
Morgan

Thanks for helping me, really appreciate :slight_smile:
How can i share you my .json because this format is not allowed.
I don’t use Smart field on the Organisation collection

@Gauthier_Cornec I’ll will try to deep dive into those files you just shared me.

Your code definition

this is organisation :

// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const Organisations = sequelize.define('organisations', {
    name: {
      type: DataTypes.STRING,
    },
    address: {
      type: DataTypes.STRING,
    },
    email: {
      type: DataTypes.STRING,
    },
  }, {
    tableName: 'organisations',
    timestamps: false,
  });

  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  Organisations.associate = (models) => {
    Organisations.belongsToMany(models.medias, {
      through: 'mediasOrganisations',
      foreignKey: 'organisationsId',
      otherKey: 'mediasId',
      as: 'mediasThroughMediasOrganisations',
    });
    Organisations.hasMany(models.playlists, {
      foreignKey: {
        name: 'organisationIdKey',
        field: 'organisationId',
      },
      as: 'playlists',
    });
    Organisations.hasMany(models.users, {
      foreignKey: {
        name: 'organisationIdKey',
        field: 'organisationId',
      },
      as: 'users',
    });
  };

  return Organisations;
};

this is playlist :


// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const Playlists = sequelize.define('playlists', {
    name: {
      type: DataTypes.STRING,
    },
    thumbnail: {
      type: DataTypes.STRING,
    },
  }, {
    tableName: 'playlists',
    timestamps: false,
  });

  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  Playlists.associate = (models) => {
    Playlists.belongsToMany(models.organisations, {
      through: 'organisationsPlaylists',
        foreignKey: 'organisationId',
      as: 'organisationsThroughOrganisationsPlaylists',
    });
    Playlists.belongsTo(models.users, {
      foreignKey: {
        name: 'authorIdKey',
        field: 'authorId',
      },
      as: 'author',
    });
    Playlists.belongsToMany(models.games, {
      through: 'gamesPlaylists',
      foreignKey: 'playlistsId',
      otherKey: 'gamesId',
      as: 'gamesThroughGamesPlaylists',
    });
    Playlists.belongsToMany(models.prosequences, {
      through: 'prosequencesPlaylists',
      foreignKey: 'playlistsId',
      otherKey: 'prosequencesId',
      as: 'prosequencesThroughProsequencesPlaylists',
    });
    Playlists.belongsToMany(models.sequences, {
      through: 'sequencesPlaylists',
      foreignKey: 'playlistsId',
      otherKey: 'sequencesId',
      as: 'sequencesThroughSequencesPlaylists',
    });
  };

  return Playlists;
};

this is user :


// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const Users = sequelize.define('users', {
    email: {
      type: DataTypes.STRING,
    },
    uuid: {
      type: DataTypes.STRING,
    },
    firstName: {
      type: DataTypes.STRING,
    },
    lastName: {
      type: DataTypes.STRING,
    },
    dateOfBirth: {
      type: DataTypes.STRING,
    },
    placeOfBirth: {
      type: DataTypes.STRING,
    },
    nationality: {
      type: DataTypes.STRING,
    },
    address: {
      type: DataTypes.STRING,
    },
    city: {
      type: DataTypes.STRING,
    },
    country: {
      type: DataTypes.STRING,
    },
    postalCode: {
      type: DataTypes.STRING,
    },
    role: {
      type: DataTypes.ENUM('user','admin','manager','pending'),
      allowNull: false,
    },
  }, {
    tableName: 'users',
    timestamps: false,
  });

  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  Users.associate = (models) => {
    Users.belongsToMany(models.organisations, {
      through: 'organisationsUsers',
      foreignKey: 'organisationId',
      as: 'organisationsThroughOrganisationsUsers',
    });
    Users.hasMany(models.playlists, {
      foreignKey: {
        name: 'authorIdKey',
        field: 'authorId',
      },
      as: 'authorPlaylists',
    });
  };

  return Users;
};


Looking at Playlists I see a relation with organisations through organisationsPlaylists. But I could find the relation in the Organisation model.

Playlists.belongsToMany(models.organisations, {
  through: 'organisationsPlaylists',
  foreignKey: 'organisationId',
  as: 'organisationsThroughOrganisationsPlaylists',
});

...
// Missing relation in Organisations
Organisations.belongsToMany(models.playlists, {
  through: 'organisationsPlaylists',
  foreignKey: 'playlistId',
  as: 'playlistsThroughOrganisationsPlaylists',
});

Can you share your Media model please ?

I’m still wondering what can cause the issue. I just try on my own with a variety of relationship but couldn’t reproduce.

Kind regards,
Morgan

there it is :

// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const Medias = sequelize.define('medias', {
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    bucket: {
      type: DataTypes.STRING,
      defaultValue: "algae_public_bucket_1",
      allowNull: false,
    },
    mediaLink: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    size: {
      type: DataTypes.INTEGER,
    },
    fileId: {
      type: DataTypes.STRING,
    },
  }, {
    tableName: 'medias',
    timestamps: false,
  });

  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  Medias.associate = (models) => {
    Medias.belongsTo(models.games, {
      foreignKey: {
        name: 'gameIdKey',
        field: 'gameId',
      },
      as: 'game',
    });
    Medias.belongsToMany(models.organisations, {
      through: 'mediasOrganisations',
      foreignKey: 'mediasId',
      otherKey: 'organisationsId',
      as: 'organisationsThroughMediasOrganisations',
    });
    Medias.hasMany(models.codages, {
      foreignKey: {
        name: 'videoIdKey',
        field: 'videoId',
      },
      as: 'videoCodages',
    });
  };

  return Medias;
};

Thank you, the only issue regarding the models definition was the one on between Organisations and Playlists.

However, I’m still a little bit confused here looking at the stack trace you shared the issue comes from directly from EmberData but I couldn’t find any medium fields or relationship. I’ll try to sync with a colleague to clear this out.

Kind regards,
Morgan

Yes i could not found it also. Thanks for helping :slight_smile:

@Gauthier_Cornec do you override the organisation create route ?

Can you also share your network calls when doing the create ? (with the response payload you can find this in the network tab)

I dont override it,

This is the network call :

There’s no call here. So the issue happen before the network call ? To be sure can you retry with the Network tab already opened ?

It should looks like this.

Can you also check that your backend receive the call for the creation ? (POST /forest/organisations)

Finally, can you share your /forest/organisations.js and /route/organisations.js files content ? It will help a lot to reduce the possible issues. :pray:

It’s seems that i don’t recieve call from forest admin to post an organisation.

Here it’s before sending the request but when i click on create nothing happend

here the forest/organisation.js:

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

// This file allows you to add to your Forest UI:
// - Smart actions: https://docs.forestadmin.com/documentation/reference-guide/actions/create-and-manage-smart-actions
// - Smart fields: https://docs.forestadmin.com/documentation/reference-guide/fields/create-and-manage-smart-fields
// - Smart relationships: https://docs.forestadmin.com/documentation/reference-guide/relationships/create-a-smart-relationship
// - Smart segments: https://docs.forestadmin.com/documentation/reference-guide/segments/smart-segments
collection('organisations', {
  actions: [],
  fields: [],
  segments: [],
});

here the route/organisations.js

// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const Organisations = sequelize.define('organisations', {
    name: {
      type: DataTypes.STRING,
    },
    address: {
      type: DataTypes.STRING,
    },
    email: {
      type: DataTypes.STRING,
    },
  }, {
    tableName: 'organisations',
    timestamps: false,
  });

  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  Organisations.associate = (models) => {
    Organisations.belongsToMany(models.medias, {
      through: 'mediasOrganisations',
      foreignKey: 'organisationsId',
      otherKey: 'mediasId',
      as: 'mediasThroughMediasOrganisations',
    });
    Organisations.hasMany(models.playlists, {
      foreignKey: {
        name: 'organisationIdKey',
        field: 'organisationId',
      },
      as: 'playlists',
    });
    Organisations.hasMany(models.users, {
      foreignKey: {
        name: 'organisationIdKey',
        field: 'organisationId',
      },
      as: 'users',
    });
  };

  return Organisations;
};
````

Hello @Gauthier_Cornec,

Thanks for sharing all this files.

The route/organisations.js should looks like this, you may have shared the wrong file.


// Create a Person
router.post('/persons', permissionMiddlewareCreator.create(), (request, response, next) => {
  // Learn what this route does here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/routes/default-routes#create-a-record
  next();
});

// Update a Person
router.put('/persons/:recordId', permissionMiddlewareCreator.update(), (request, response, next) => {
  // Learn what this route does here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/routes/default-routes#update-a-record
  next();
});

// Delete a Person
router.delete('/persons/:recordId', permissionMiddlewareCreator.delete(), (request, response, next) => {
  // Learn what this route does here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/routes/default-routes#delete-a-record
  next();
});

Ok, so it happen during the creation on the front side itself. We will check again the front config of your UI. For the moment, we don’t understand from where forest-medium can come. The medium field isn’t in any of your files, am I right ? (just to be sure)

I’m gonna be back in a few moment.

Kind regards,
Morgan

No I don’t have any forest-medium file.
Thanks

Hey again,

Can you share the route/organisations.js it would reassure us.

Can you try something to reduce the specter of possible issue. The idea is to comment all associations with the organisations, restart your server, then by enabling the associations one-by-one and test the organisation creation, it could lead us to the one that failed. :pray:

Kind regards,
Morgan