Shamoon
Shamoon

Reputation: 43501

How can I have a many-to-many association with Sequelize?

I have two models, a Person and a Car as defined:

module.exports = function(sequelize, DataTypes) {
  var Person;
  Person = sequelize.define('Person', {
    name: {
      type: DataTypes.STRING,
      allowNull: false
    },
    profession: {
      type: DataTypes.STRING,
      allowNull: false
    }
  }, {
    classMethods: {
      associate: function(models) {
        return Person.hasMany(models.Car, {
          foreignKey: 'PersonId'
        });
      }
    }
  });

  return Person;
};

and

module.exports = function(sequelize, DataTypes) {
  var Car;
  Car = sequelize.define('Car', {
    vin: {
      type: DataTypes.STRING,
      allowNull: false
    },
    color: {
      type: DataTypes.STRING,
      allowNull: false
    }
  }, {
    classMethods: {
      associate: function(models) {
        return Car.hasMany(models.Person, {
          foreignKey: 'CarId'
        });
      }
    }
  });

  return Car;
};

This does what one would expect and create three tables: Persons, Cars and CarsPersons.

I've added a few Cars to the table and now I want to add a Person to the Persons table. I have a CarId of 15, let's say. So when adding a Person, I do:

DB.Person.create({name: 'My Name', profession: 'Lawyer'}).complete(function(err)....

How can I create an association in the CarsPersons table to have a CarId of 15 and a PersonId of whatever this new ID is?

Upvotes: 0

Views: 156

Answers (2)

agchou
agchou

Reputation: 747

In addition to the answer above (add method), Sequelize injects methods that provide some convenience in dealing with setting foreign keys and the like.

In the case of many-to-many associations, you can call .create[AssociatedModel] and the keys are automatically set for you. For example, if you wanted to create a new car instance that belonged to a certain person, it would work similarly to this:

// Find person who owns the car
DB.Person.find(5)
  .then(function (person) {

    // Will create entry with PersonId: 5, CarId: createdCarId
    person.createCar({ ... })
  })

The solution above by Jan works well when both instances already exist but I think that in general the associations should be set at creation.

Check out the docs for associations to see the other injected methods: http://sequelize.readthedocs.org/en/latest/api/associations/#hasmanytarget-options

Upvotes: 1

Jan Aagaard Meier
Jan Aagaard Meier

Reputation: 28788

DB.Person.create({name: 'My Name', profession: 'Lawyer'}).then(function (person) {
  // On latest master you can pass the id directly:
  person.addCar(15);

  // On older versions you will have to load the car object first:
  DB.Car.find(15).then(function (car) {
    person.addCar(car);
  });
});

Upvotes: 1

Related Questions