lucid: Creating records with BelongsToMany relation and custom primary keys not working
I’m having an issue creating records with a model relationship as described below. It seems as if its trying to insert the primary key value of the foreign table rather than the related primary key value defined in the relation.
Tables:
parties: id(pk), type(varchar) # type is either U=user, T=team
user: id(pk), party_id(int)
team: id(pk), name(varchar), party_id(int)
team_user: team_party_id(int), user_party_id(int)
Relations:
class User extends Model {
teams () {
return this.belongsToMany('App/Models/Team', 'user_party_id', 'team_party_id', 'party_id', 'party_id')
}
}
class Team extends Model {
users () {
return this.belongsToMany('App/Models/User', 'team_party_id', 'user_party_id', 'party_id', 'party_id')
}
}
create a new team for a user and add them to it:
await user.teams().create({name: 'Team 1'})
SQL executed:
insert into `parties` (`type`) values (?);
insert into `teams` (`created_at`, `name`, `party_id`, `updated_at`) values (?, ?, ?, ?);
select `team_party_id`, `user_party_id` from `team_user` where `user_party_id` = ?;
insert into `team_user` (`team_party_id`, `user_party_id`) values (?, ?);
Instead of inserting the value of teams.party_id
in the team_user
table, it uses teams.id
even though the relation has been set up with relatedPrimaryKey
as party_id
(see Relations section above).
I think I have narrowed down the problem to here:
// @adonisjs/lucid/src/Lucid/Relations/BelongsToMany.js from line 772 onwards:
async save (relatedInstance, pivotCallback) {
// ...
const pivotRows = await this.attach(relatedInstance.primaryKeyValue, pivotCallback)
// should be: `await this.attach(relatedInstance[this.relatedPrimaryKey], pivotCallback)`
// ...
}
Instead of passing relatedInstance.primaryKeyValue
into the this.attach()
relatedInstance[this.relatedPrimaryKey]
as per the relatedPrimaryKey
value defined in the relationship.
For the time being I had to use this solution to achieve the result I wanted:
await user.teams().attach((await use('App/Models/Team').create({name: 'Team 1'})).party_id)
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 15 (7 by maintainers)
Would you try it from github develop branch and lemme if all works fine. Feel free to try it under different use cases
First of all, thank you for taking the time to compose an elaborate response for me.
Sadly this does not address the issue entirely.
I will try to detail eveything below. Apologies for some repetition.
Users and Teams
Products
Party
select * from products where party_id in (<user id>, ...<team ids>)
Example
Pivot table
Relations
Tests
Currently my work around:
So as you can see my issue is creating teams and attaching an existing user (or attaching users to an existing team).
From what I understand the
relatedPrimaryKey
parameter you pass into thebelongsToMany()
should act as the joining factor regardless of if you are doing a fetch or a create/update but maybe you can shed some light on that for me.Thanks