One-to-Many Relationships
Now we want be able to post reviews on games as a user and games can also have many reviews.
There is a one-to-many relationship between Users and Reviews. There is also a one-to-many relationship between Games and Reviews.
For reviews, in Reviews.js:
const Reviews = db.define(
'Reviews',
{
review_id: {
type: DataTypes.INTEGER.UNSIGNED,
primaryKey: true,
autoIncrement: true
},
created_by: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
references: {
model: Users,
key: 'user_id'
}
},
fk_game_id: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
references: {
model: Games,
key: 'game_id'
}
},
title: {
type: DataTypes.STRING(255),
allowNull: false
},
content: {
type: DataTypes.TEXT,
allowNull: false
},
rating: {
type: DataTypes.TINYINT.UNSIGNED,
allowNull: false
}
},
{
tableName: 'reviews',
timestamps: true,
createdAt: 'created_at',
updatedAt: 'updated_at'
}
);
For games, in Games.js:
const Games = db.define(
'Games',
{
game_id: {
type: DataTypes.INTEGER.UNSIGNED,
primaryKey: true,
autoIncrement: true
},
title: {
type: DataTypes.STRING(255),
allowNull: false
},
description: {
type: DataTypes.TEXT,
allowNull: false
},
price: {
type: DataTypes.DECIMAL(5, 2), // ie 999.99
allowNull: false
},
year: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false
}
},
{
tableName: 'games',
timestamps: true,
createdAt: 'created_at',
updatedAt: 'updated_at'
}
);
Relationship
The relationships would be:
In Reviews.js:
// users can have many reviews
Users.hasMany(Reviews, {
foreignKey: 'created_by',
as: 'reviews'
});
// each review has an author/user
Reviews.belongsTo(Users, {
foreignKey: 'created_by',
as: 'author'
});
// games can have many reviews
Games.hasMany(Reviews, {
foreignKey: 'fk_game_id',
as: 'reviews'
});
// each review has a game
Reviews.belongsTo(Games, {
foreignKey: 'fk_game_id',
as: 'game'
});
Querying this Relationship
It is also similar to one-to-one relationships.
Create
If you want to create a user and their (many) reviews all at once:
await Users.create({
username: "vadim",
email: "vadim@example.com",
password: "hole_in_the_roof",
reviews: [
{
fk_game_id: 1,
title: "beautiful story",
content: "a breathtaking and heartbreaking adventure",
rating: 10
},
{
fk_game_id: 2,
title: "decent fun",
content: "good enough graphics, at least it was cheap",
rating: 6
}
]
}, { include: "reviews" });
Multiple Includes
When you want to get a review, you would need to join data from two other models, the Users and Games models. To do so, you use an array.
In reviews.js:
await Reviews.findAll({
include: [
{
association : 'author',
attributes: { exclude: ['password'] }
},
'game'
]
});