Загрузка KeystoneJS CloudinaryImage через API

Кажется, не хватает документации по этой теме. Я пытаюсь загрузить изображение и установить для него значение avatar: { type: Types.CloudinaryImage } в моей модели Keystone.

Я публикую контент в виде составных данных формы со следующей структурой: avatar: <raw_data>. Вот как я обрабатываю это в своем API:

exports.upload_avatar = function(req, res) {
    if (!req.files.avatar) {
        console.info('Request body missing');
        return res.status(400).json({ message: 'Request body missing', code: 20 });
    }
    req.current_user.avatar = req.files.avatar;
    req.current_user.save();
} 

где current_user — модель мангуста. Что меня сбивает с толку, так это то, как установить поле типа CloudinaryImage для данных, которые я получаю в API.


person Nikolay Derkach    schedule 08.02.2017    source источник


Ответы (3)


Таким образом, вместо того, чтобы просто установить для аватара необработанные данные (что отлично подойдет, например, для строкового поля), вам нужно пройти через обработчик обновления, который вызывает специальный путь {path}_upload в облачное изображение.

Затем вы сможете выполнить avatar.getUpdateHandler, возможно, следуя этот пример.

person Jake Stockwin    schedule 09.02.2017
comment
Хм, я пробовал req.current_user.getUpdateHandler(req).process(req.files, {fields: 'avatar'}, function(err) {}), а также вызывал обработчик для поля avatar. Ошибок не вызывает, хотя файл тоже не загружается. - person Nikolay Derkach; 09.02.2017

Хорошо, покопавшись в исходном коде, я нашел способ сделать это:

exports.upload_avatar = function(req, res) {
    req.current_user.getUpdateHandler(req).process(req.files, {fields: 'avatar'}, function(err) {
      if (err) {
          return res.status(500).json({ message: err.message || '', code: 10 });
      }
      res.send('');
    });
}

У меня были следующие ошибки:

  • используйте getUpdateHandler для обновления поля CloudinaryImage.
  • используйте «волшебное» имя для полей данных составной формы, которые вы отправляете в API: {field_name}_upload, что в моем случае будет avatar_upload.
  • процесс req.files, который представляет собой словарь с именами ваших полей в качестве ключей и данными вашего файла в качестве значений. req.body пуст из-за некоторой постобработки с multer.
  • вызвать обработчик обновления для вашей модели трапецеидальных искажений (сначала вам нужно получить ее с помощью find), а не для определенного поля. Затем укажите {fields: <>}, чтобы ограничить его область действия, иначе могут возникнуть некоторые проблемы, такие как ошибки проверки, пытающиеся обновить весь объект.
person Nikolay Derkach    schedule 10.02.2017

Я хотел бы поделиться тем, что сработало для меня. Процесс довольно странный, но после добавления этого кода вся проверка модели работает просто отлично, и устанавливаются облачные загрузки.

post(req, res, next) {
  const newBundle = new Bundle(); //A mongoose model
  newBundle.getUpdateHandler(req).process(req.body, (err) => {
    if (err) {
      return res.status(500).json({
        error: err.message,
      });
    }
    return res.json(newBundle);
  });
}

При отправке в конечную точку все, что вам нужно сделать, это убедиться, что вы установили для полей файла значение {databaseFieldName}_upload.

person Jt oso    schedule 20.09.2018