Sequelize - Many to Many

Objectives

  • Create a join table and utilize it in a many-to-many relationship
  • Use Sequelize's helper methods to add relationships between two different models.

If we wanted to expand our models to include a many to many relationship, we can use a many to many relationship via a join table. We will be expanding our data model to include posts and tags.

Very Important Name - your models singular

sequelize model:create --name post --attributes title:string,body:string,authorName:string

sequelize model:create --name tag --attributes name:string

sequelize model:create --name postsTags --attributes postId:integer,tagId:integer

Update your Associations

In order to associate posts to tags in a many to many fashion, you will need to update the associations on the posts and tags.

post.js

associate: function(models) {
 models.post.belongsToMany(models.tag, {through: "postsTags"})
}

tags.js

associate: function(models) {
  models.tag.belongsToMany(models.post, {through: "postsTags"})
}

Examples

Create a post

db.post.findOrCreate({
  where: {
    title: "taco",
    body: "burrito",
    authorName: "Brian"
  }
}).spread(function(post, created) {
  console.log(post.get());
});

Add a unique tag to a Post.

In order to add a unique tag to a post, we must first try to find or create a tag, in order to make sure it is in fact unique.

Secondly, we must attach a post to the tags, using some built in helpers.

Some ORM has capabilities to do a bulk create on an object associations, but that kind of logic is not built in Sequelize.

db.post.findOrCreate({
  where: {
    title: "taco",
    body: "burrito",
    authorName: "Brian"
  }
}).spread(function(post, created) {
  db.tag.findOrCreate({
    where: {name: "food"}
  }).spread(function(tag, created) {
    console.log(tag.get());
  });
});

Get all posts that use a tag

Sequelize generates helper functions that allow you to get related items. For instance, if you wanted to find all posts that used a given tag:

db.tag.find({
  where: {name: "food"}
}).then(function(tag) {
  tag.getPosts().then(function(posts) {
    console.log("These posts are tagged with " + tag.name + ":");
    posts.forEach(function(post) {
      console.log("Post title: " + post.title);
    });
  });
});

results matching ""

    No results matching ""