Trouble with custom relationship table

Pretty sorry, but I can’t find any valid reason for the app to behave like that.

Let’s sum this up just so we are all aligned:

  • You have a collection (software_feature) that references 3 others collections (feature, feature_mapping_status, software)
  • You aren’t using any composite key in your app
  • One of your environment have the expected behavior (Development?) and another one that don’t (Dev?)
  • The composite ids you are redirected to does not match anything of your record
  • The page you are redirected to does not match with the record you’ve selected

Since none of the proposed solution did work, I think I would need some more informations. Could you do the exact same video as your first one with your dev console on the network tab opened ? That would be helpful :pray:

1 Like
  • Correct
  • Correct
  • Yes Development is fine but 3 other (dev, beta, production) are not behaving properly
  • Yes, when I click on on SoftwareFeature collection the shown id not seem to correspond to any other ids
  • The page I am redirected to DOES MATCH the record (only the id is messed up but having this messed up ids wont allow me to update the record

here is new video with logs from the deployed dev environment
(something actually broke this time, i tried to do same thing in devellopement environement (same code and similar data) and it didnt break.

I am also adding other corresponding models:

Feature:

/* eslint-disable import/no-cycle */
import { Sequelize, DataTypes, BelongsToManySetAssociationsMixin } from 'sequelize';
import { Models } from 'types/model';
import { FeatureLevel } from './feature-level';
import { Recommandation } from './recommandation';
import { SoftwareFeature } from './software-feature';
import BaseModel from './base-model';
import { Software } from './software';

export class Feature extends BaseModel {

  public nameEn!: string;
  public description!: string;

  public featureLevel!: FeatureLevel;
  public softwares!: SoftwareFeature[];
  public recommandations!: Recommandation[];

  setSoftwares: BelongsToManySetAssociationsMixin<Software, Software['id']>;

  static associate = (models: Models) => {

    Feature.belongsToMany(models.featureMappingStatus, {
      through   : 'software_feature',
      foreignKey: 'feature_id',
      otherKey  : 'feature_mapping_status_id',
    });

    Feature.belongsToMany(models.software, {
      through   : 'software_feature',
      foreignKey: 'feature_id',
      otherKey  : 'software_id',
      as        : 'softwares'
    });

    Feature.belongsToMany(models.recommandation, {
      through   : 'recommandation_feature',
      foreignKey: 'feature_id',
      otherKey  : 'recommandation_id',
    });

    Feature.belongsToMany(models.label, {
      through   : 'label_feature',
      foreignKey: 'feature_id',
      otherKey  : 'label_id',
    });

    Feature.belongsTo(models.featureLevel, {
      as: 'featureLevel'
    });

  };

}

export default (sequelize: Sequelize): typeof Feature => {

  Feature.init({
    nameEn: {
      type: DataTypes.STRING, field: 'name_en'
    },
    description: { type: DataTypes.STRING },

    // uuid      : { type: DataTypes.UUID, },
    created_at: {
      type        : 'TIMESTAMP',
      defaultValue: 'now()',
    },
    updated_at: { type: DataTypes.DATE, },
  }, {
    hooks: {
      async afterCreate(feature) {

        const { software } = sequelize.models;

        await feature.setSoftwares(await software.findAll() as Software[]);

      },
    },
    tableName  : 'feature',
    modelName  : 'feature',
    underscored: true,
    sequelize
  });

  return Feature;

};

FeatureMappingStatus:

import { Sequelize, DataTypes } from 'sequelize';
import BaseModel from './base-model';

export class FeatureMappingStatus extends BaseModel {

  public name!: string;

}

export default (sequelize: Sequelize): typeof FeatureMappingStatus => {

  FeatureMappingStatus.init({

    // uuid      : { type: DataTypes.UUID, },
    name      : { type: DataTypes.STRING, },
    created_at: {
      type        : 'TIMESTAMP',
      defaultValue: 'now()',
    },
    updated_at: { type: DataTypes.DATE, },
  }, {
    tableName  : 'feature_mapping_status',
    modelName  : 'featureMappingStatus',
    underscored: true,
    sequelize
  });

  return FeatureMappingStatus;

};

Software

/* eslint-disable import/no-cycle */
import { Sequelize, DataTypes, BelongsToManySetAssociationsMixin } from 'sequelize';
import { Models } from 'types/model';
import { Label } from './label';
import { SoftwareType } from './software-type';
import { Recommandation } from './recommandation';
import { Feature } from './feature';
import { SoftwareFeature } from './software-feature';
import BaseModel from './base-model';

export class Software extends BaseModel {

  public domain!: string;
  public supportPage!: string;
  public name!: string;
  public logo!: string;

  public softwareType!: SoftwareType;
  public recommandations?: Recommandation[];
  public features!: Feature[];
  public labels?: Label[];
  public softwareFeature!: SoftwareFeature[];

  setFeatures: BelongsToManySetAssociationsMixin<Feature, Feature['id']>;

  static associate = (models: Models) => {

    Software.belongsTo(models.softwareType);

    Software.belongsToMany(models.recommandation, {
      through   : 'recommandation_software',
      foreignKey: 'software_id',
      otherKey  : 'recommandation_id',
    });

    Software.belongsToMany(models.feature, {
      through   : 'software_feature',
      foreignKey: 'software_id',
      otherKey  : 'feature_id',
    });

    Software.hasMany(models.label);

    Software.hasMany(models.softwareFeature, {
      foreignKey: {
        field: 'software_id',
      },
      as: 'softwareFeature'
    });

  };

}

export default (sequelize: Sequelize): typeof Software => {

  Software.init({

    // uuid       : { type: DataTypes.UUID, },
    name       : { type: DataTypes.STRING, },
    logo       : { type: DataTypes.STRING, },
    domain     : { type: DataTypes.STRING, },
    supportPage: {
      type: DataTypes.STRING, field: 'support_page'
    },
    created_at: {
      type        : 'TIMESTAMP',
      defaultValue: 'now()',
    },
    updated_at: { type: DataTypes.DATE, },
  }, {
    hooks: {
      async afterCreate(software) {

        const { feature } = sequelize.models;

        await software.setFeatures(await feature.findAll() as Feature[]);

      },
    },
    tableName  : 'software',
    modelName  : 'software',
    underscored: true,
    sequelize
  });

  return Software;

};

Thanks :pray:

From what I can see in your video, your lumber backend receives a valid id as a query params when dealing with the HTTP GET request. The only way to get back a composite id in this case is located here. This info comes from the adapters/sequelize.js, which reads data directly from sequelize.

In order to be sure, could you please console.log(SoftwareFeature.primaryKeys); in a file that requires this model (Just after the import statement in a routes/*.js file for example) ? I want to see the sequelize object associated to SoftwareFeature, in order to see if sequelize flags your FK as primary keys

so I added this

in routes/software.ts

// Get a list of softwares
router.get('/software', permissionMiddlewareCreator.list(), (request, response, next) => {

  console.log(SoftwareFeature.primaryKeyAttribute);

  // Learn what this route does here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/routes/default-routes#get-a-list-of-records
  next();

});

and the result was

id

In my devellopment environement that is fine and in the other one too

let me know if giving you acces to the repo could help or anything!

Hi @Benjamin_Marquis :wave:, according to the Sequelize documentation about belongsToMany, you should put in through argument the model like this

Software.belongsToMany(models.feature, {
      through   : models.softwareFeature,
      foreignKey: 'software_id',
      otherKey  : 'feature_id',
    });

Can you test that please and let me know if it’s help ?

Hi @Arnaud_Moncel thanks for helping isnt it similar to ?

Software.belongsToMany(models.feature, {
      through   : 'software_feature',
      foreignKey: 'software_id',
      otherKey  : 'feature_id',
    });

Sequelize’s documentation suggests to do this, if you don’t do it, it can surely cause issue.
I’m not completely sure the issue comes from here, but we can test it.

no luck unfortunately!

I ran through the code and I found a variable we’re using. Could I have the result of this one please.
Can you do something like this please ?

// Get a list of softwares
router.get('/software', permissionMiddlewareCreator.list(), (request, response, next) => {

  console.log(SoftwareFeature.primaryKeys);

  // Learn what this route does here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/routes/default-routes#get-a-list-of-records
  next();

});

Thanks for help,

so i get

Property 'primaryKeys' does not exist on type 'typeof SoftwareFeature'

with

console.log(SoftwareFeature.primaryKeys);

but

console.log(SoftwareFeature.primaryKeyAttribute);

gives me

id

Hello @Benjamin_Marquis :wave:

Sorry for this long journey, I’ll jump on this issue and try to figure out where does the id 51|23 come from.

May I ask you the payload of the /forest/software_feature/6200 response please? You can simply past the response data from the network, this should be enough :+1:

Thanks in advance.

Steve.

Hi @Steve_Bunlon thanks a lot for helping.

so the request

Request URL: https://dev-admin.tooly.ai/forest/software_feature?fields%5BfeatureMappingStatus%5D=name&fields%5Bfeature%5D=nameEn&fields%5BsoftwareFeature%5D=createdAt%2CfeatureMappingStatus%2Cid%2CupdatedAt%2Cfeature%2Csoftware%2Cupdated_at&fields%5Bsoftware%5D=name&page%5Bnumber%5D=1&page%5Bsize%5D=15&searchExtended=0&sort=-id&timezone=America%2FToronto

gave this payload

{"data":[{"type":"software_feature","id":"163|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":163,"software_id":41}},{"type":"software_feature","id":"162|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":162,"software_id":41}},{"type":"software_feature","id":"161|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":161,"software_id":41}},{"type":"software_feature","id":"160|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":160,"software_id":41}},{"type":"software_feature","id":"159|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":159,"software_id":41}},{"type":"software_feature","id":"158|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":158,"software_id":41}},{"type":"software_feature","id":"157|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":157,"software_id":41}},{"type":"software_feature","id":"156|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":156,"software_id":41}},{"type":"software_feature","id":"155|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":155,"software_id":41}},{"type":"software_feature","id":"154|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":154,"software_id":41}},{"type":"software_feature","id":"153|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":153,"software_id":41}},{"type":"software_feature","id":"152|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":152,"software_id":41}},{"type":"software_feature","id":"151|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":151,"software_id":41}},{"type":"software_feature","id":"150|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":150,"software_id":41}},{"type":"software_feature","id":"149|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":149,"software_id":41}}]}

I give you some other request/response in case it help
request

Request URL: https://dev-admin.tooly.ai/forest/software_feature?fields%5BfeatureMappingStatus%5D=name&fields%5Bfeature%5D=nameEn&fields%5BsoftwareFeature%5D=createdAt%2CfeatureMappingStatus%2Cid%2CupdatedAt%2Cfeature%2Csoftware%2Cupdated_at&fields%5Bsoftware%5D=name&page%5Bnumber%5D=1&page%5Bsize%5D=15&searchExtended=0&sort=-id&timezone=America%2FToronto

response payload

{"data":[{"type":"software_feature","id":"163|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":163,"software_id":41}},{"type":"software_feature","id":"162|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":162,"software_id":41}},{"type":"software_feature","id":"161|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":161,"software_id":41}},{"type":"software_feature","id":"160|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":160,"software_id":41}},{"type":"software_feature","id":"159|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":159,"software_id":41}},{"type":"software_feature","id":"158|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":158,"software_id":41}},{"type":"software_feature","id":"157|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":157,"software_id":41}},{"type":"software_feature","id":"156|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":156,"software_id":41}},{"type":"software_feature","id":"155|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":155,"software_id":41}},{"type":"software_feature","id":"154|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":154,"software_id":41}},{"type":"software_feature","id":"153|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":153,"software_id":41}},{"type":"software_feature","id":"152|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":152,"software_id":41}},{"type":"software_feature","id":"151|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":151,"software_id":41}},{"type":"software_feature","id":"150|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":150,"software_id":41}},{"type":"software_feature","id":"149|41","attributes":{"createdAt":"2020-07-30T22:03:46.875Z","updatedAt":"2020-07-30T22:03:46.875Z","feature_id":149,"software_id":41}}]}

request

Request URL: https://dev-admin.tooly.ai/forest/software?fields%5BsoftwareType%5D=name&fields%5Bsoftware%5D=createdAt%2Cdomain%2Cid%2Clogo%2Cname%2CupdatedAt%2CsoftwareType%2Cupdated_at%2CsupportPage&page%5Bnumber%5D=1&page%5Bsize%5D=15&searchExtended=0&sort=-id&timezone=America%2FToronto

payload

{"data":[{"type":"software","id":"41","attributes":{"id":41,"name":"Salut fuck test","logo":null,"domain":null,"supportPage":null,"updated_at":"2020-07-30T22:03:46.848Z","createdAt":"2020-07-30T22:03:46.848Z","updatedAt":"2020-07-30T22:03:46.848Z"},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/41/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/41/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/41/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/41/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/41/relationships/softwareFeature"}}}}},{"type":"software","id":"40","attributes":{"id":40,"name":"LeadMaster","logo":null,"domain":"https://leadmastercrm.com/LP/Capterra_Sept2018/index.html?","supportPage":"https://leadmastercrm.com/LP/Capterra_Sept2018/index.html","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/40/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/40/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/40/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/40/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/40/relationships/softwareFeature"}}}}},{"type":"software","id":"39","attributes":{"id":39,"name":"Daylite for Mac","logo":null,"domain":"https://www.marketcircle.com/","supportPage":"https://www.marketcircle.com/learn","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/39/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/39/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/39/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/39/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/39/relationships/softwareFeature"}}}}},{"type":"software","id":"38","attributes":{"id":38,"name":"TeamGate","logo":null,"domain":"https://www.teamgate.com/","supportPage":"https://support.teamgate.com/hc/en-us","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/38/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/38/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/38/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/38/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/38/relationships/softwareFeature"}}}}},{"type":"software","id":"37","attributes":{"id":37,"name":"InfoFlo","logo":null,"domain":"https://infoflosolutions.com/","supportPage":"https://infoflosolutions.com/tutorials/crm/lessons/getting-started/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/37/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/37/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/37/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/37/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/37/relationships/softwareFeature"}}}}},{"type":"software","id":"36","attributes":{"id":36,"name":"Really Simple Systems","logo":null,"domain":"https://www.reallysimplesystems.com/small-business-crm","supportPage":"https://www.reallysimplesystems.com/resources/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/36/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/36/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/36/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/36/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/36/relationships/softwareFeature"}}}}},{"type":"software","id":"35","attributes":{"id":35,"name":"Salesmate","logo":null,"domain":"https://www.salesmate.io/","supportPage":"https://www.salesmate.io/resources/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/35/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/35/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/35/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/35/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/35/relationships/softwareFeature"}}}}},{"type":"software","id":"34","attributes":{"id":34,"name":"GreenRope","logo":null,"domain":"https://software-info.capterra.com/greenrope-complete-crm/","supportPage":"https://software-info.capterra.com/greenrope-complete-crm/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/34/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/34/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/34/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/34/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/34/relationships/softwareFeature"}}}}},{"type":"software","id":"33","attributes":{"id":33,"name":"SutiCRM","logo":null,"domain":"https://www.sutisoft.com/crm-software/","supportPage":"hhttps://www.sutisoft.com/crm-software/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/33/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/33/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/33/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/33/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/33/relationships/softwareFeature"}}}}},{"type":"software","id":"32","attributes":{"id":32,"name":"Gold-Vision","logo":null,"domain":"https://www.gold-vision.com/","supportPage":"https://www.gold-vision.com/resources/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/32/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/32/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/32/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/32/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/32/relationships/softwareFeature"}}}}},{"type":"software","id":"31","attributes":{"id":31,"name":"Claritysoft CRM","logo":null,"domain":"https://claritysoft.com/getclarity-v9/","supportPage":"https://claritysoft.com/getclarity-v9/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/31/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/31/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/31/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/31/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/31/relationships/softwareFeature"}}}}},{"type":"software","id":"30","attributes":{"id":30,"name":"Honeybook","logo":null,"domain":"https://www.honeybook.com/","supportPage":"https://www.honeybook.com/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/30/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/30/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/30/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/30/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/30/relationships/softwareFeature"}}}}},{"type":"software","id":"29","attributes":{"id":29,"name":"Hatchbuck","logo":"https://www.thesmbguide.com/images/hatchbuck-420x320-20190315.png","domain":"https://www.hatchbuck.com/","supportPage":"https://www.help.hatchbuck.com/en/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/29/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/29/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/29/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/29/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/29/relationships/softwareFeature"}}}}},{"type":"software","id":"28","attributes":{"id":28,"name":"NetSuite","logo":"https://jp.smartsheet.com/sites/default/files/2019-09/oracle.png","domain":"https://www.netsuite.com/","supportPage":"https://www.netsuite.com/portal/services/partner-services.shtml","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/28/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/28/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/28/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/28/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/28/relationships/softwareFeature"}}}}},{"type":"software","id":"27","attributes":{"id":27,"name":"Drip","logo":"https://apps.3dcart.com/assets/images/drip-wordmark.png","domain":"https://www.drip.com/","supportPage":"https://www.drip.com/learn/docs/manual/","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{"softwareType":{"data":{"type":"softwareType","id":"1"},"links":{"related":{"href":"/forest/software/27/relationships/softwareType"}}},"recommandations":{"links":{"related":{"href":"/forest/software/27/relationships/recommandations"}}},"features":{"links":{"related":{"href":"/forest/software/27/relationships/features"}}},"labels":{"links":{"related":{"href":"/forest/software/27/relationships/labels"}}},"softwareFeature":{"links":{"related":{"href":"/forest/software/27/relationships/softwareFeature"}}}}}],"included":[{"type":"softwareType","id":"1","attributes":{"id":1,"name":"CRM","updated_at":null,"createdAt":"2020-07-09T19:15:19.217Z","updatedAt":null},"relationships":{}}]}

Tell me if it was not what you where expected or if I can do more :slight_smile:

Thanks for the payload. We clearly see the issue here, the software_feature records are returned with the composite key as id (the first payload).

If I’m not mistaken, your software_feature records are indexed using their own id, not a composite key of foreign key. Do you confirm ?

Steve.

Yes this is correct!

Ok, I’m really interested to know what’s in the primaryKeys as @Arnaud_Moncel suggested. Using typescript you can not use it because it not defined in the types. Can you deactivate TS for the ligne :

console.log(SoftwareFeature.primaryKeys);

And run the code again?

Thanks.

1 Like

Here is the result
(sorry @Arnaud_Moncel been fairly new to typsecript i didnt know about // @ts-ignore)

{ id:
   { type:
      INTEGER {
        options: {},
        _length: undefined,
        _zerofill: undefined,
        _decimals: undefined,
        _precision: undefined,
        _scale: undefined,
        _unsigned: undefined },
     primaryKey: true,
     autoIncrement: true,
     Model: softwareFeature,
     fieldName: 'id',
     _modelAttribute: true,
     field: 'id' } }

Ok thanks, this is correct.

Would you mind giving us the DDL structure of your DB please ?

The only thing I can propose so far is to reproduce your configuration on my end and to debug.

Steve.

Thanks for your patient here it is @Steve_Bunlon

maybe i could give you access to the repo (and include a database snapshot in there ?) (or clone the repo to a public one?)