directus-sync icon indicating copy to clipboard operation
directus-sync copied to clipboard

Seeds, support M2A relations.

Open shadiramadan opened this issue 9 months ago • 2 comments

The seeds feature is awesome! Thank you for your hard work @EdouardDem ! (Do you have a buy me a coffee link?)

I am, however, running into an issue for M2A relations. This might be a feature request if it's known it is unsupported.

The error itself is vague-

[09:26:46.786] ERROR (70683): Cannot read properties of null (reading 'startsWith')
    err: {
      "type": "TypeError",
      "message": "Cannot read properties of null (reading 'startsWith')",

But after adding a few console logs- We see that it tries to call collection.startsWith on null (targetModel).

Logged in SeedDataMapper.initialize()

{ collection: 'nav_sections_items', field: 'item', targetModel: null }

This ends up returning null- because the line before it fails to retrieve the the related_collection from the relation field- because it doesn't have one.

 const targetModel = yield this.schemaClient.getTargetModel(this.collection, field);

The item field snapshot

{
  "collection": "nav_sections_items",
  "field": "item",
  "related_collection": null,
  "meta": {
    "junction_field": "nav_sections_id",
    "many_collection": "nav_sections_items",
    "many_field": "item",
    "one_allowed_collections": [
      "nav_sections",
      "links"
    ],
    "one_collection": null,
    "one_collection_field": "collection",
    "one_deselect_action": "nullify",
    "one_field": null,
    "sort_field": null
  }
}

The complexity here is that the targetModel of this item field has to be one of one_allowed_collections which comes from one_collection_field.

In my seeds example I added

targetModel ?? field === "item" && this.collection === "nav_sections_items" ? "links" : null

and seeded only one item type and that did end up working perfectly but that shouldn't be a static value. The targetModel could have multiple options.

So this line in data-mapper initialize:

this.idMappers[field] =
    this.idMapperClientFactory.forCollection(targetModel);

Needs to be dynamic based on the record's one_collection_field.

Versions:

  • Directus-Sync version: 3.2.3 (latest)
  • Directus version: 11.5.1 (latest)
  • Database: PostgreSQL
  • Directus environment: Docker/Self-hosted

shadiramadan avatar Mar 21 '25 16:03 shadiramadan

Is there yet any workaround for M2A relationships?

antontranelis avatar Aug 14 '25 12:08 antontranelis

Hi @antontranelis @shadiramadan , The seed features was not designed to handle M2A relationships. I'm trying to figure out how I can implement this. For instance, I don't have any workaround.

EdouardDem avatar Aug 14 '25 15:08 EdouardDem