I have a many-to-many
between Songs
and People
. The join model isn't specified because it only has three columns: primary key, song_id
and person_id
.
Bookshelf definitions:
//Song
Bookshelf.model("Song", {
tableName: "songs",
people: function() {
return this.belongsToMany("Person", "people_songs");
}
});
//Person
Bookshelf.model("Person", {
tableName: "people",
songs: function() {
return this.belongsToMany("Song", "people_songs");
}
});
Given a song id and person id, I want to add a row to the join table. Attach seems to be the correct method to use on the model instance, so in a controller I can do...
Models
.Song
.forge()
.where({id: 1})
.people()
.attach( new Models.Person({id: 1}) )
.then(function(instance) {
res.send();
});
When I query out the rows, song_id
is null? (I should make the columns notNullable()
but that's besides the point...)
I also tried updatePivot
like this:
Models
.Song
.forge()
.where({id: 1})
.people()
.updatePivot({song_id: 1, person_id: 1})
.then(function(instance) {
res.send();
});
But that didn't even insert anything into the join table. However, if I log out the result of the updatePivot
promise I get this:
relatedData: {
targetTableName: "songs",
targetIdAttribute: "id",
joinTableName: "people_songs",
foreignKey: "song_id"
otherKey: undefined,
parentId: undefined,
parentTableName: "people",
parentIdAttribute: "id",
parentFk: undefined
}
Found a solution here in a repo issue.
//get the model
Models
.Song
.forge({id: 12})
//but I have no idea why save is being used here instead of fetch
.save()
.then(function(model) {
//get the other model you want to add to the join table
return Models
.Person
.forge({id: 56})
.save()
.then(function(target) {
//need to send both references down the promise chain
return {target: target, model: model};
});
})
.then(function(references) {
return references
.model
//get the belongsToMany relation specified in your Model definition, it returns a collection
.people()
//attach the target to the collection, not the model instance
.attach(references.target);
})
.then(function(relation) {
res.send();
})
The result was
people_songs
id | person_id | song_id
___________________________
3 | 56 | 12