Advanced associations using Sequelize
Setting up ‘Many-to-many-through’ association between models using junction/through table.
This is Part 6 of multi-part series on ExpressJS.
You can find Part 1 here. It talks about building a basic express api and setting up mocha for testing.
You can find Part 2 here. It talks about setting up PostgreSQL, sequelize for connecting express api with databases.
You can find Part 3 here. It talks about setting up associations (has many as well as belongs to) between two models.
You can find Part 4 here. It talks about setting up user authentication based on email and password.
You can find Part 5 here. It talks about using json web token to protect a route.
In this part of the series, we will take User and Post models, which are already associated via ‘Author’ , and add another association which will be ‘Saved’.
One user can have many saved posts, and one post can be saved by many users.
We will then set up appropriate routes to test expected response.
- A specific post should tell us who is the author, but also who have saved this post.This will not be a protected route.
- A specific user should have authored posts as well as saved posts. This will be a protected route.
Let’s handle the tests first —
Update factories
So we set it up two ways
post.addSavedBy(reader)
andreader.addSaved(post)
This is just to showcase the functions offered by sequelize on our models.
Add specific post test —
The whole test now looks like this —
Update our JWT test —
So we check for both Written
posts and Saved
posts associated with our author.
So our tests are all set up, time for coding.
Add a through table via migration
We will create a new table in our database, that only stores association information about which user saved which post.
Each row in our through table represents a save action — One user has saved one post.
So, if we have to look up all saved posts for a user, or for a post who have saved it — We will (or rather sequelize will) make use of this table.
This is called as a ‘Junction or Through Table’.
We need to create a migration to add the table to our database.
migration:generate
andmigration:create
are both aliases which achieve the same goal — to create a migration file.
Update the migration file —
So we name this through table as SavedPosts
.
Time to use it for associating our User
and Post
models.
Add association in models
Add to User model —
User.belongsToMany(models.Post, { through: ‘SavedPosts’, as: ‘Saved’ })
Add to Post model —
Post.belongsToMany(models.User, { through: ‘SavedPosts’, as: ‘savedBy’ })
Here, we alias the association as Saved
and SavedBy
depending on the model. It makes more semantic sense to say
- A User Saved a post
and
- A Post was Saved By a user.
Run the migration —
sequelize db:migrate
as you know well by now.
We have now successfully constructed our through table, added the association for both models, and updated database tables accordingly.
Time to connect to our request/response flow using routes and controllers.
Add a route —
We go to routes/posts.js
and add a route for specifc post.
router.get(‘/:id’, postsController.getSpecificPost)
This route handlet the request for following URL — https:<host>/posts/id
for ex. https://articleWebsite.com/posts/7
. 7 here is the id of the post and handled as a parameter OR param
in our API.
Add a method to controller —
Add getSpecificPost
method to our posts controller —
getSpecificPost
method will search for a post with matching id and return it as response.
Update User controller —
We will also update user controller to attach saved posts whenever we request for a user.
So we have set up the routes, and connected controller actions to handle requests received on those routes. We have also set up associations between models and have ran the migrations to reflect the new relationship in our database table.
The tests should go green now and they do indeed.
Craft Academy is a Tech Education Provider that aims to bring new talent to the market and help to solve the shortage of tech workers. We are founded on the belief that modern development standards, agile methodologies, and business skills are fundamental for IT professionals.
Our primary service is a 12-week coding bootcamp designed to provide individuals with a foundation of skills that allows them to enter the industry as junior developers.
With that foundation, our learners find employment in various industries or start their own businesses that bring new innovations to the market.
Would you like to know more about what we do? Follow us here on Medium, Facebook, Twitter or visit our website.