Обновление записи с помощью 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()

Как видите, он обрабатывает множество вариантов для вас.

Другие вопросы по тегам