What I'm trying to achieve is: when a new competition is added, I need to create a row in the the table team_comp conteining the same id of field "competition_teams" of table competition and the extra data that i send by request. I'll have a lot of competitions but each competition has one team_comp that belongs to it. If i delete a competition, its team_comp row must be deleted.
table competition :
| id | name | competition_teams |
| 1 | A | 32 |
table team_comp :
| id | competition_id | test_h |
| 3 | 32 | 1 |
In my models/index.js I'm defining associations like this:
// Competition
db.competition.hasOne(db.competition_team, {as: 'compId', foreignKey : 'competition_id'});
// Competition Teams
db.competition_team.belongsTo(db.competition, {as: 'compTeam', foreignKey : 'competition_id', onDelete: 'CASCADE'});
By doing this, I get the wrong foreign key. It creates me a foreign key in table ** team_comp ** pointing to competion.id and not into competition.competition_teams (which is what i want). How can I let it points to competition.competition_teams?
This is how I add a new competition (controllers/ competition.js):
import db from '../models/index';
const Competition = db.competition;
const Competition_teams = db.competition_team;
// create competition
const create = (req, res) => {
// generating a random id for the competition
var competition_teams = Math.floor(Math.random() * 100);
let {
name,
test_h,
} = req.body;
// create new Competition
let newCompetition = {
name,
competition_teams // this must be also added in table team_comp, column competition_id
}
let newCompetitionTeams = {
test_h
}
Competition.create(newCompetition)
.then(Competition => {
res.json({ Competition });
})
.catch(err => {
console.log("Error: " + err);
return res.status(500).json({ err });
});
// creating teams association
Competition_teams.create(newCompetitionTeams)
.then(Competition_teams => {
res.json({ Competition_teams });
})
.catch(err => {
console.log("Error: " + err);
return res.status(500).json({ err });
});
}
You need to specify the sourceKey
property in the association - if ignored it will use table + id Reference
The name of the attribute to use as the key for the association in the source table. Defaults to the primary key of the source table
See the following complete example:
class Competition extends Sequelize.Model {
}
Competition.init({
id: {
primaryKey: true,
type: Sequelize.INTEGER,
allowNull: false
},
name: {
type: Sequelize.STRING(36)
},
team_competition_id: {
type: Sequelize.INTEGER,
allowNull: false,
}
}, {
sequelize,
modelName: 'competition',
tableName: 'competitions',
timestamps: false
});
class Team_Competition extends Sequelize.Model {
}
Team_Competition.init({
id: {
primaryKey: true,
type: Sequelize.INTEGER,
allowNull: false
},
name: {
type: Sequelize.STRING(36)
},
}, {
sequelize,
modelName: 'team_competition',
tableName: 'team_competitions',
timestamps: false
});
// use sourceKey here - also make sure you specify `cascade` and `hooks` property
Competition.hasOne(Team_Competition, {sourceKey: 'team_competition_id', foreignKey: 'id', onDelete: 'cascade', hooks: true});
// tests
// create the team_competition
const team_competition = await Team_Competition.create({
id: 1,
name: 'Team A'
});
// create the competition
const competition = await Competition.create({
id: 1,
name: 'Comp A',
team_competition_id: team_competition.id
});
// test the join
const competitions = await Competition.findAll({
include: [
{
attributes: ['id', 'name'],
model: Team_Competition,
}
],
raw: true
});
// delete and verify cascade
await competition.destroy();
Will result in the following SQL generated and executed:
Executing (default): INSERT INTO "team_competitions" ("id","name") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "competitions" ("id","name","team_competition_id") VALUES ($1,$2,$3) RETURNING *;
// query
Executing (default): SELECT "competition"."id", "competition"."name", "competition"."team_competition_id", "team_competition"."id" AS "team_competition.id", "team_competition"."name" AS "team_competition.name" FROM "competitions" AS "competition" LEFT OUTER JOIN "team_competitions" AS "team_competition" ON "competition"."team_competition_id" = "team_competition"."id";
// cascade deletes
Executing (default): DELETE FROM "team_competitions" WHERE "id" = 1
Executing (default): DELETE FROM "competitions" WHERE "id" = 1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.