Сохранить объект с ассоциациями в Sequelizejs

Насколько я могу судить, используя Sequelizejs, кажется, что не существует способа сохранить ассоциации объектов, когда сам объект сохраняется.

Например, у меня есть контакт, который может иметь 1 или более номер телефона. В настоящее время у меня есть что-то вроде этого для ассоциации:

global.db.Contact.hasMany(global.db.PhoneNumber, {as: 'phoneNumbers'});

Используя конечную точку отдыха, я хотел бы опубликовать новый контактный объект (с любыми предоставленными номерами телефонов) и сохранить его в базе данных. Мой объект запроса выглядит примерно так:

{
    firstName: "john",
    lastName: "Doe",
    phoneNumbers: [
        { number: "555-555-5555", type: "home" }
    ]
}

Сейчас я передаю этот объект для сборки:

var contact = Contact.build(req.body);

И затем вызовите save (я знаю, что я мог бы использовать create вместо build/save, но у нас есть пользовательская логика в save для отслеживания измененных данных и какой пользователь сделал модификацию)

contact.save();

Это вызывает следующую ошибку, которая имеет смысл.

column "phoneNumbers" of relation "Contacts" does not exist

Звонок sql пытается установить значение столбца "phoneNumbers", которого не существует. Я, очевидно, не хочу, чтобы это делалось... Я действительно хотел бы, чтобы навалом создавался каждый номер телефона в массиве с идентификатором создаваемого мной контакта.

Единственным примером, который я нашел, было следующее: https://gist.github.com/sdepold/3040391, и я действительно не хочу этого делать... Поскольку я исхожу из конечной точки отдыха, Я хотел бы, чтобы сделать эту операцию в целом (у меня будет много моделей с ассоциациями). Мне также нужно будет делать эти операции навалом (для импорта контактов из других источников), поэтому я бы предпочел, чтобы это было минимальное количество вызовов sql. Кто-нибудь нашел хороший способ сделать это?

Ответ 1

Я использую этот код

var createUser = function(req, reply) {
    db.User.create(req.payload).success(function(user) {
        saveGroups(req, reply, user);
    }).error(function(err) {
        console.error('Error occured', err);
        reply('Error');
    });
};

var saveGroups = function(req, reply, user) {
    db.UserGroup.destroy("user_id=" + user.id).success(function() {
        var groups = req.payload.userGroups;
        if (groups && groups.length > 0) {
            for (var i = 0; i < groups.length; i++) {
                groups[i].user_id = user.id;
            }
            db.UserGroup.bulkCreate(groups).success(function() {
                reply(user);
            }).error(function(err) {
                console.error('Error occured', err);
                reply('Error');
            });
        } else {
            reply(user);
        }
    }).error(function(err) {
        console.error('Error occured', err);
        reply('Error');
    });
};
  • Пользователь - это модель, которая имеетMany UserGroup
  • req.payload приходит JSON
  • уничтожить (...), чтобы сначала удалить ассоциации (в случае, если мы делаем обновление)

Ответ 2

В Sequelize v4 появилась новая функция, которая позволяет создавать экземпляр вместе со всеми связанными экземплярами.

В вашем случае это позволяет добавить несколько телефонных номеров против одного пользователя, как указано ниже.

return Contact.create({
  firstName: 'John',
  lastName: 'Doe',
  PhoneNumbers: [
    {
      number: '555-555-5555',
      type: 'home'
    },
    {
      number: '555-555-7777',
      type: 'work'
    }
  ]  
}, {
  include: [{
    association: Product.PhoneNumber
  }]
});

Подробную документацию можно найти здесь Sequelize Docs - Создание с ассоциациями