Strongloop: HasAndBelongsToMany Polymorphic Relationship with uuids

I am trying to use HasAndBelongsToMany polymorphic relation when using uuids. My problem is that I cannot teach Strongloop to use an id with a string as a type instead of a number in the required many-to-many table. This leads to SQL errors when creating new relationships.

Let me explain, for example:

I have two models: CartCollection and Cart. The collection should have different carts, including the cart itself. Cart and CartCollection have uuids instead of simple IDs. Show this as a property in model-json. The problem lies in the many-to-many polymorphic relationships between them. I am trying to use the HasAndBelongsToMany polymorphic relationship to figure this out. In this table, I am also trying to override the id type.

This is my JSON code:

{
  "name": "SaleCartCollection",
  "plural": "SaleCartCollections",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "id": {
      "type": "string",
      "length": 36,
      "id": true
    }    
  },
  "validations": [],
  "relations": {
    "saleCartsPoly": {
      "type": "hasMany",
      "model":"SaleCart",
      "polymorphic" : {
        "as": "saleCartsPoly",
        "invert": true
      },
      "through": "SaleCartCartCollectionLink"
    }
  },
  "acls": [],
  "methods": []
}

{
  "name": "SaleCart",
  "plural": "SaleCarts",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "id": {
      "type": "string",
      "length": 36,
      "id": true
    }
  },
  "validations": [],
  "relations": {
    "SaleCartCollections": {
      "type": "hasAndBelongsToMany",
      "model": "SaleCartCollection",
      "polymorphic": {
        "as":"saleCartsPoly",
        "foreignKey" : "saleCartsPolyId",
        "discriminator" : "saleCartsPolyType"
      },
      "through": "SaleCartCartCollectionLink"
    }
  },
  "acls": [],
  "methods": []
}

{
  "name": "SaleCartCartCollectionLink",
  "base": "PersistedModel",
  "properties": {
    "saleCartsPolyId": {
      "type": "string",
      "length": 36
    }
  },
  "validations": [],
  "relations": {
  },
  "acls": [],
  "methods": []
}

      

If I now try to POST a new CartCollection to an existing cart, I get this output:

loopback:connector:mysql SQL: INSERT INTO `SaleCartCartCollectionLink`(`saleCartsPolyId`,`saleCartsPolyType`,`saleCartCollectionId`) VALUES(?,?,?), params: [null,"SaleCart","bad7a6fc-1798-49c5-a0cb-fa59eba5b3a4"] +8ms
loopback:connector:mysql Error: {"code":"ER_BAD_FIELD_ERROR","errno":1054,"sqlState":"42S22","index":0} +11ms

      

I found out this was happening because Strongloop was ignoring my property definition in Through-model. It's still a number that you can see here in the model schematic in explorer:

[
  {
    "saleCartsPolyId": 0,
    "id": 0,
    "saleCartsPolyType": "",
    "saleCartCollectionId": ""
  }
]

      

Does anyone have an idea if I am doing something wrong or if this is a bug in Strongloop?

Regards

Niklas

+3


source to share


1 answer


I am Niklas's employee, and we solved our problem as follows.

We define

  • "Cart hasMany CartCollection via CartCartCollectionLink" relation is polymorphic "like a cart"
  • "CartCollection hasMany Cart via CartCartCollectionLink" polymorphic "as cartCollection"
  • and here's the important part: the two polymorphic "CartCartCollectionLink belongs to [Cart | CartCollection]" relationships are polymorphic with polymorphic .idType: string !

The interesting part is that the idType property is incorrectly set for the HasAndBelongsToMany relationship.

Someone might want to take a look at relation-definition.js: 1566:

  if (params.polymorphic) {
    var polymorphic = polymorphicParams(params.polymorphic);
    options.polymorphic = polymorphic; // pass through
    var accessor = params.through.prototype[polymorphic.as];
    if (typeof accessor !== 'function') { // declare once
      // use the name of the polymorphic rel, not modelTo

      // *** you might want to set idType here: ***
      params.through.belongsTo(polymorphic.as, { polymorphic: true });
    }
  }

      



CartCartCollectionLink.json

{
  "name": "SaleCartCartCollectionLink",
  "relations": {
    "saleCarts": {
      "type": "belongsTo",
      "model": "SaleCart",
      "foreignKey": "saleCartId",
      "polymorphic": {
        "as": "saleCart",
        "idType": "string"
      }
    },
    "saleCartCollections": {
      "type": "belongsTo",
      "model": "SaleCartCollection",
      "foreignKey": "saleCartCollectionId",
      "polymorphic": {
        "as": "saleCartCollection",
        "idType": "string"
      }
    }
  }
}

      

Cart.json

{
  "name": "SaleCart",
  "properties": {
    "id": {
      "type": "string",
      "length": 36,
      "id": true
    }
  },
  "relations": {
    "saleCartCollections": {
      "type": "hasMany",
      "model": "SaleCartCollection",
      "foreignKey": "saleCartId",
      "through": "SaleCartCartCollectionLink",
      "polymorphic": {
        "as": "saleCart"
      }
    }
  }
}

      

CartCollection.json

{
  "name": "SaleCartCollection",
  "properties": {
    "id": {
      "type": "string",
      "length": 36,
      "id": true
    }
  },
  "relations": {
    "saleCarts": {
      "type": "hasMany",
      "model": "SaleCart",
      "foreignKey": "saleCartCollectionId",
      "through": "SaleCartCartCollectionLink",
      "polymorphic": {
        "as": "saleCartCollection"
      }
    }
  }
}

      

+1


source







All Articles