Обновление записи с помощью CloudKit JS
CloudKit JS предлагает методы для сохранения, удаления и извлечения записей, но не существует простых способов обновления существующих. Документация объясняет, как это сделать:
var query = {
operationType : 'forceUpdate',
recordType: 'List',
record : {
recordName : 'TheRecordIWannaUpdate',
fields: { TheFieldToUpdate: { 'value': 42}}
}
};
container.publicCloudDatabase.performQuery(query).then(function(response) {
if(response.hasErrors) {
console.log(response.errors[0]);
} else {
console.log('It's working')
}
});
Я попробовал этот код, и он возвращает It's working
однако моя запись не обновляется, что не так с этим кодом?
2 ответа
Для обновления записи вы можете использовать recordChangeTag. Нужна последняя запись ChangeTag.
Когда вы выбираете запись с сервера, вы получаете текущую версию этой записи, которая существует на сервере. Однако в любое время после извлечения записи другие пользователи могут сохранить более новую версию записи на сервере. Каждый раз, когда запись сохраняется, сервер обновляет токен изменения записи на новое значение. Когда вы сохраняете свой экземпляр записи на сервере, сервер сравнивает токен в вашей записи с токеном на сервере. Если два токена совпадают, сервер знает, что вы изменили последнюю версию записи и что ваши изменения могут быть применены сразу. Если два токена не совпадают, сервер применяет политику сохранения, указанную вашим приложением, чтобы определить, как действовать дальше.
пример
var record = {
recordType: 'List',
recordName: TheRecordIWannaUpdate,
recordChangeTag: TheRecordTag,
fields: {
TheFieldToUpdate: {
value: 42
}
}
};
Политика сохранения не работает для меня, но вы можете добавить ее.
var options = {
zoneName: undefined,
operationType : 'forceUpdate'
};
container.publicCloudDatabase.saveRecord(record,options)
.then(function(response) {
if(response.hasErrors) {
console.log(response.errors[0]);
} else {
console.log("It's working");
}
});
Как говорится в документации, update
является правильным типом операции для использования в большинстве ситуаций.
обновление | Обновить существующую запись. Только указанные вами поля будут изменены.
Всегда возможно, что запись была обновлена другим клиентом между моментом, когда вы прочитали ее и попытались применить новые обновления. recordChangeTag
так сервер узнает, какую версию вы прочитали, поэтому в документации указано, что вам нужно отправить ее вместе с операцией обновления.
Если operationType является обновлением, установите ключ recordChangeTag на значение существующей записи [в словаре записей].
Когда вы пытаетесь обновить запись, которая уже была обновлена кем-то другим, вы получите конфликт от сервера, потому что ваш recordChangeTag устарел, и вы должны обрабатывать этот конфликт любым способом, который имеет смысл в вашем приложении. Может быть, вы хотите сказать пользователю и, возможно, вы просто хотите объединить изменения.
В особых ситуациях может потребоваться принудительное обновление. В этом случае вы можете использовать forceUpdate
operationType, говорящий серверу игнорировать конфликты и принимать это обновление, и в этом случае вам не нужно включать recordChangeTag
,
forceUpdate | Обновите существующую запись независимо от конфликтов. Создает запись, если она не существует.
Если вы используете нормальный update
OperationType и вы получите успех (не конфликт), то запись обязательно должна быть обновлена на сервере. Если это не так, то происходит что-то еще.
Стоит отметить, что вам может быть удобнее использовать RecordsBatchBuilder при отправке изменений на сервер. Вот пример того, что вы можете сделать с ним:
myDatabase.newRecordsBatchBuilder()
.createOrUpdate(record1)
.create(record2)
.update(record3)
.forceUpdate(record4)
.delete(record5)
.commit()
Как видите, он обрабатывает множество вариантов для вас.