Setting up a difficult relationship

Sorry, I’m a bit lost and can’t really figure things out using the docs. Can someone tell me how to achieve the following:

Data model and setup

  • I have an external replica data source collection X with a hard-coded schema, that defines a primaryKey x.
  • I have a mongoose data source collection Y, that defines a field z, which is an array of strings. The strings in this array match x.

What I want to achieve in terms of relationships

  • Have linked records of X available in the UI, when I visit a record of Y.
  • When I create a new record Y, i can add several records of X to the corresponding field z.

Thanks!

Context

  • Project name:jurata-2
  • Team name: jurata
  • Environment name: Development
  • Agent (forest package) name & version:
    "@forestadmin/agent": "^1.13.1",
    "@forestadmin/datasource-mongoose": "^1.4.2",
    "@forestadmin/datasource-replica": "^1.0.1",
  • Database type: mongo and external api

Hey @David_Roegiers :wave:

I’m eager to see you are already using our Replica strategy, and sorry for the delayed response.

I made a quick test on my end, and you should be able to achieve such a result using the following:

  1. On your mongoose datasource, use the model flattener to create a model based on your [Number] field.

Using

The following should allow you to convert the field test to a model

  1. Once done, customize the generated collection (In my case, it’s account_test), and define the ManyToOne relation.

You may need to hide via the UI all the uncessary steps, but hopefully, you should be able to implement what you are looking for in terms on read operation.

Handling the write operations in such case may be a bit tricky, so we’ll be waiting to check if this solution is acceptable on your end before going further.

Just let us know :pray:

Hey @jeffladiray

Thank you for your reply and support!

To be honest, it is difficult for me to fully grasp your proposition. I am not sure what account_test is, and also do not comprehend how the field test fits into the ManyToOne relationship.

But, I gave it a try anyway, and it did not really work. I get (according to my analogy written above):

Error: Column not found: 'Y.z'

at Function.checkColumn (/Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/decorators/relation/collection.ts:176:13)
    at Function.checkKeys (/Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/decorators/relation/collection.ts:158:33)
    at RelationCollectionDecorator.checkForeignKeys (/Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/decorators/relation/collection.ts:124:35)
    at RelationCollectionDecorator.addRelation (/Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/decorators/relation/collection.ts:29:10)
    at /Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/collection-customizer.ts:540:52
    at DecoratorsStack.applyQueuedCustomizations (/Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/decorators/decorators-stack.ts:101:41)
    at async DataSourceCustomizer.getDataSource (/Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/datasource-customizer.ts:158:5)
    at async /Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/datasource-customizer.ts:61:24
    at async DecoratorsStack.applyQueuedCustomizations (/Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/decorators/decorators-stack.ts:101:7)
    at async DataSourceCustomizer.getDataSource (/Users/davidroegiers/Jurata/jurata-next/forest-2/node_modules/@forestadmin/datasource-customizer/src/datasource-customizer.ts:158:5)

Even though it is defined in the Mongoose schema, as

...
z: [String],
...

Any idea why?

To be honest, it is difficult for me to fully grasp your proposition

Sorry about that. Your use-case is pretty advanced but I’ll do my best to be clearer :slight_smile:

Let’s go back to the issue. In your case, and to be able to defined a ManyToOne relationship using addManyToOneRelation, you’ll need to have a model associated to your array of string.

We provide such option using the { asModel } property when creating your mongoose datasource. In your example, { asModels: { YourModel_Y: ['z'] } } should work as expected, and should generate a new collection visible in your Forestadmin UI.

Once this collection works, then adding the relation via addManyToOneRelation should be straightforward using addManyToOneRelation('relationName', 'YourModel_Y', { foreignKey: 'yourForeignKey', foreignKeyTarget: 'id' })

If that’s easier, you can send me your models definitions via DM, so I can share with you a more adapted version of the code :+1:

Thanks for taking the time to specify. Indeed, these cross data source relationships with arrays are quite advanced. Hope you don’t mind me taking the new agent for a drive like that. :slight_smile:

It works! :mirror_ball: Took a slightly different approach, though, by adding addManyToOneRelation('relationName', 'YourModel_X', { foreignKey: 'content', foreignKeyTarget: 'x' }) to the newly generated model.

Happy monday :+1:

2 Likes