-
-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(pinia-orm): add belongsToMany relation function (#79)
* feat(pinia-orm): add belongsToMany relation function * feat(pinia-orm): make the size smaller * refactor(pinia-orm): add missing pinia to dev dependency * chore: get rid of double ci * chore: vue2 tests somehow failing ... for later * test(pinia-orm): add custom keys test * chore: add on push trigger back * refactor: code clean up * docs: update documentation * chore: dep update * docs: fix small typo
- Loading branch information
Showing
17 changed files
with
770 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
--- | ||
title: Many To Many | ||
description: '' | ||
--- | ||
|
||
Many-to-many relations are slightly more complicated than other relationships. An example of such a relationship is a user with many roles, where the roles are also shared by other users. For example, many users may have the role of "Admin". To define this relationship, three models are needed: User, Role, and RoleUser. | ||
|
||
The RoleUser contains the fields to hold id of User and Role model. We'll define `user_id` and `role_id` fields here. The name of RoleUser model could be anything, but for this example, we'll keep it this way to make it easy to understand. | ||
|
||
Many-to-many relationships are defined by defining `this.belongsToMany()`. | ||
|
||
```js | ||
class User extends Model { | ||
static entity = 'users' | ||
|
||
static fields () { | ||
return { | ||
id: this.attr(null), | ||
roles: this.belongsToMany(Role, RoleUser, 'user_id', 'role_id') | ||
} | ||
} | ||
} | ||
|
||
class Role extends Model { | ||
static entity = 'roles' | ||
|
||
static fields () { | ||
return { | ||
id: this.attr(null) | ||
} | ||
} | ||
} | ||
|
||
class RoleUser extends Model { | ||
static entity = 'roleUser' | ||
|
||
static primaryKey = ['role_id', 'user_id'] | ||
|
||
static fields () { | ||
return { | ||
role_id: this.attr(null), | ||
user_id: this.attr(null) | ||
} | ||
} | ||
} | ||
``` | ||
|
||
The argument order of the `belongsToMany` attribute is: | ||
|
||
1. The Related model which is in this case Role. | ||
2. Intermediate pivot model which is in this case RoleUser. | ||
3. Field of the pivot model that holds the id value of the parent – User – model. | ||
4. Field of the pivot model that holds the id value of the related – Role – model. | ||
|
||
You may also define custom local key at 5th and 6th argument. | ||
|
||
```js | ||
class User extends Model { | ||
static entity = 'users' | ||
|
||
static fields () { | ||
return { | ||
id: this.attr(null), | ||
roles: this.belongsToMany( | ||
Role, | ||
RoleUser, | ||
'user_id', | ||
'role_id', | ||
'user_local_id', | ||
'role_local_id' | ||
) | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### Defining The Inverse Of The Relationship | ||
|
||
To define the inverse of a many-to-many relationship, you can place another `belongsToMany` attribute on your related model. To continue our user roles example, let's define the users method on the Role model: | ||
|
||
```js | ||
class User extends Model { | ||
static entity = 'users' | ||
|
||
static fields () { | ||
return { | ||
id: this.attr(null) | ||
} | ||
} | ||
} | ||
|
||
class Role extends Model { | ||
static entity = 'roles' | ||
|
||
static fields () { | ||
return { | ||
id: this.attr(null), | ||
users: this.belongsToMany(User, RoleUser, 'role_id', 'user_id') | ||
} | ||
} | ||
} | ||
|
||
class RoleUser extends Model { | ||
static entity = 'roleUser' | ||
|
||
static primaryKey = ['role_id', 'user_id'] | ||
|
||
static fields () { | ||
return { | ||
role_id: this.attr(null), | ||
user_id: this.attr(null) | ||
} | ||
} | ||
} | ||
``` | ||
|
||
As you can see, the relationship is defined the same as its `User` counterpart, except referencing the `User` model and the order of 3rd and 4th argument is reversed. | ||
|
||
### Access Intermediate Model | ||
|
||
Working with many-to-many relations requires the presence of an intermediate model. Pinia ORM provides some helpful ways of interacting with this model. For example, let's assume our `User` object has many `Role` objects that it is related to. After accessing this relationship, we may access the intermediate model using the `pivot` attribute on the models. | ||
|
||
```js | ||
const user = User.query().with('roles').first() | ||
|
||
user.roles.forEach((role) => { | ||
console.log(role.pivot) | ||
}) | ||
``` | ||
|
||
Notice that each `Role` model we retrieve is automatically assigned a `pivot` attribute. This attribute contains a model representing the intermediate model and may be used like any other model. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.