Sequelize create включить существующий объект

У меня проблема с продолжением при создании со связанной моделью с «уникальным» значением. Это работает, когда я создаю «книгу» с новой «категорией», но если «категория» уже существует, выдает ошибку, потому что она пыталась продублировать «уникальное» значение. Есть ли способ заставить sequelize.create попытаться использовать findAndCreate в связанной модели?


Моя установка

Книга:

const Book = sequelize.define('book', {
  title: Sequelize.STRING,
})

Категория:

const Category = sequelize.define('category', {
  id: Sequelize.BIGINT,
  name: {
    type: Sequelize.STRING,
    unique: true,
  },
})

и отношения:

Book.belongsTo(Category, { foreignKey: 'category_id' })

Итак, когда я создаю книгу, я могу написать:

Book.create(
  {
    title: 'Book',
    category: {
      name: 'Foo'
    }
  }, {
    include: [
      {
        model: Category
      }
    ]
  }
)

если после этого я создам другую книгу:

Book.create(
  {
    title: 'Another Book',
    category: {
      name: 'Foo'
    }
  }, {
    include: [
      {
        model: Category
      }
    ]
  }
)

он выдает ошибку, говоря, что имя категории должно быть уникальным

Зачем нужны две категории с одинаковым названием? Это противоречит цели категории, да? Кроме того, я думаю, вам нужно уже создать несколько кошек. И когда вы создаете книгу, вы указываете идентификатор категории, а не название.

Wexoni 26.03.2018 13:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
1 651
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для всех, у кого возник такой же вопрос, это было мое окончательное решение:

В моем services.js я создал функцию create, которая получает request(req), и все мои модели уже инициализированы.

create: (req, models) => {
  const { category, ...rest } = req.body
  if (category && category.name && !rest.category_id) {
    return models.Category
      .findOrCreate({ 
        where: { 
          name: category.name 
        }
      })
      .then(([returnedCategory]) => {
        return models.Book.create(
          {
            ...rest, 
            category_id: returnedCategory.id 
          }, 
          { ...defaultOptions(models) }
        )
      })
    } else {
      return models.Book.create(rest, { ...defaultOptions(models) })
    }
},

defaultOptions выглядит так:

const defaultOptions = models => {
  return {
    attributes: {
      exclude: ['category_id', 'created_at', 'updated_at'],
    },
    include: [
      { model: models.Category, attributes: ['id', 'name'] },
    ],
  }
}

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