I have model A that can have one or more rows of model B affiliated with it. The relation only has to go one way.

I ran:

result = await A.query()
  .where('id', 123) // 123 is an already existing model A
  .insertGraph([
    {
      B: [{id: 456}] // 456 is an already existing model B
    }
   ]);

But I get an error Key (id)=(456) already exists.

To my understanding, Objection is trying to make a new model B with an id 456 where I just want to add a relation between the the two rows A:123 and B:456.

1 Answers

1
Rashomon On Best Solutions

Since you are updating, I would not use insertGraph(). It could be done with upsertGraph() using refs. But this method is a bit complex, ideally I would just do:

const a = await A
  .query()
  .findById(123);

const numRelatedRows = await a.$relatedQuery('B')
  .relate(456)

Using upsertGraph(), you would relate child 456 this way, but the rest of child (if existing) would be unrelated. You can modify the behaviour of upsert with a lot of options, but for me in your case $relatedQuery() is the way to go:

const result = await A.upsertGraphAndFetch(
  {
    id: 123,
    B: [
         {#ref: 456} // relate 456, and unrelate the rest, since not present here
       ]
  }
)