问题描述
说我有这个模式:
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: ...,"789"] ## notice kept 123,and Now want 789
}
}) { ... }
}
这将导致Fauna出现instance not unique
错误。因为它试图连接123,但是已经在ClientServices集合(管理m-m关系的自动生成的集合)中。
是否有一种简单的方法可以在不使用UDF的情况下在一次呼叫中断开所有连接并重新连接我想要的连接?
解决方法
我相信您可以在相同的突变中连接和断开连接(没有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
功能的简单解决方案,也许Fauna GQL API可以为操作顺序提供一些保证。如果disconnect
总是在connect
之前执行,则可以始终断开orig
并连接replacements
。这种保证似乎是合理的,因为我真的无法想象在同一个API调用中连接并立即断开关系的理智的原因。
至此,动物区系已创建,断开连接并建立连接。 您似乎正在寻找一种替换,它可以自动计算差异并在断开连接和连接方面采取正确的措施。我认为目前使用纯GraphQL无法实现。您确实需要编写一个UDF。对于其他人来说,这可能也是一个有趣的功能,因此它可能是论坛上的功能请求的不错选择:https://forums.fauna.com/