Как заменить все соединения в отношениях «многие ко многим» в Fauna

#graphql #faunadb

#graphql #faunadb

Вопрос:

Допустим, у меня есть эта схема:

 Client {
 services: [Service] @relation(name: "ClientServices")
}
Service {
 clients: [Client] @relation(name: "ClientServices")
}
  

И я хочу подключить некоторые службы к клиенту, например:

 mutation {
 updateClient(id: ..., data : {
   services:  {
     connect: ["123", "456"] ## where there are valid service _id's
  }
 }) { ... }
}
  

Фантастика. Отлично работает.
Но теперь я хочу заменить все соединения (службы) другими, но при этом сохранить службу 123.

 mutation {
 updateClient(id: ..., data : {
   services:  {
     connect: ["123", "789"] ## notice kept 123, and now want 789
  }
 }) { ... }
}
  

Это приведет к instance not unique ошибке от Fauna. Потому что он пытается подключить 123, но он уже находится в коллекции ClientServices (автоматически сгенерированная коллекция, которая управляет отношениями m-m.).

Есть ли простой способ отключить все и повторно подключить те, которые я хочу, за один вызов без UDF?

Ответ №1:

Я считаю, что вы можете подключаться и отключаться в одной и той же мутации (без UDF):

 mutation {
 updateClient(id: ..., data : {
   services:  {
     connect: ["789"],
     disconnect: ["456"]
  }
 }) { ... }
}
  

Это предполагает, что у вас есть возможность вычислять разницу на клиенте. Например, с помощью Lodash:

 const _filter = require('lodash/filter');
const _find = require('lodash/find');
const _map = require('lodash/map');

let orig = [{id: "123"}, {id: "456"}]
let replacements = [{id: "123"}, {id: "789"}]

let toConnect = _filter(replacements, o => !_find(orig, {id: o.id}))
let toDisconnect = _filter(orig, o => !_find(replacements, {id: o.id}))

mutate(
    // ...
    {
        connect: _map(toConnect, 'id'),
        disconnect: _map(toDisconnect, 'id')
    },
    // ...
)
  

В качестве простого решения для обеспечения replace функциональности, возможно, API Fauna GQL может предоставить некоторые гарантии порядка операций. Если disconnect всегда выполняется перед connect , то вы всегда можете отключиться orig и подключиться replacements . Эта гарантия кажется разумной, поскольку я не могу представить разумную причину для подключения и немедленного отключения отношения в одном и том же вызове API.

Комментарии:

1. Спасибо @colllin — я потратил слишком много времени на написание UDF для замены .. и не подумал об объединении двух (подключение и отключение). Это отлично работает!

Ответ №2:

На данный момент Фауна имеет create, disconnect и connect. Похоже, вы ищете замену, которая автоматически вычисляет разницу и выполняет правильные действия с точки зрения отключения и подключения. Я не думаю, что в настоящее время это возможно с чистым GraphQL. Вам действительно нужно будет написать UDF. Это может быть интересной функцией и для других, поэтому она может быть хорошим кандидатом для запроса функций на форумах: https://forums .fauna.com /

Комментарии:

1. Разве вы не можете просто вычислить разницу в JS и отправить оба поля disconnect and connect в вашем запросе GQL?

2. Да, это возможно, это, вероятно, было не совсем понятно из моего ответа. Однако я предположил, что пользователь искал что-то, где ему не нужно вычислять это в клиенте.