# Relationships
This chapter describes how the GraphQL-Plugin interacts with relationships. All relationships work out of the box. We take the examples from the Vuex-ORM documentation for definition relationships and show what GraphQL queries will be generated.
# One To One
TIP
See the One To One section in the Vuex-ORM documentation.
Is eager loaded automatically.
Models:
class Profile extends Model {
static entity = 'profiles';
static fields () {
return {
id: this.uid(),
age: this.string(''),
sex: this.string(''),
userId: this.string(''),
user: this.belongsTo(User, 'userId')
}
}
}
class User extends Model {
static entity = 'users';
static fields () {
return {
id: this.uid(),
name: this.string(''),
profile: this.hasOne(Profile, 'userId')
}
}
}
Fetch Query for User:
query Users {
users {
nodes {
id
name
profile {
id
age
sex
userId
}
}
}
}
Fetch Query for Profile:
query Profiles {
profiles {
nodes {
id
age
sex
userId
user {
id
name
}
}
}
}
# One To Many
TIP
See the One To Many section in the Vuex-ORM documentation.
BelongsTo is eager loaded automatically while HasMany is not eager loaded.
Models:
class Comment extends Model {
static entity = 'comments';
static fields () {
return {
id: this.uid(),
postId: this.string(''),
content: this.string(''),
post: this.belongsTo(Post, 'postId')
}
}
}
class Post extends Model {
static entity = 'posts';
static fields () {
return {
id: this.uid(),
title: this.string(''),
content: this.string(''),
comments: this.hasMany(Comment, 'postId')
}
}
}
Fetch Query for Comment:
query Comments {
comments {
nodes {
id
postId
content
post {
id
content
title
}
}
}
}
As you can see the post is eager loaded.
Fetch Query for Post:
query Posts {
posts {
nodes {
id
content
title
}
}
}
As you can see the comments are not eager loaded.
# Many To Many
TIP
See the Many To Many section in the Vuex-ORM documentation.
Is NOT eager loaded automatically, so we add a eagerLoad field to User.
Models:
class User extends Model {
static entity = 'users';
static eagerLoad = ['roles'];
static fields () {
return {
id: this.uid(),
email: this.string(''),
roles: this.belongsToMany(Role, RoleUser, 'userId', 'roleId')
}
}
}
class Role extends Model {
static entity = 'roles';
static fields () {
return {
id: this.uid(),
name: this.string(''),
users: this.belongsToMany(User, RoleUser, 'roleId', 'userId')
}
}
}
class RoleUser extends Model {
static entity = 'roleUser';
static primaryKey = ['roleId', 'userId'];
static fields () {
return {
roleId: this.string(''),
userId: this.string('')
}
}
}
Fetch Query for User:
query Users {
users {
nodes {
id
email
roles {
nodes {
id
name
}
}
}
}
}
Roles are eager loaded because of the eagerLoad
definition in the User
model.
Fetch Query for Role:
query Roles {
roles {
nodes {
id
name
}
}
}
# Has Many Through
TIP
See the Has Any Through section in the Vuex-ORM documentation.
Is NOT eager loaded automatically.
In this example we have a Product which can belong to many ProductGroups. And a ProductGroup can have many Products. This is a classical n:m relation type, which we setup via HasManyThrough and a Pivot Model (ProductsProductGroup)
Models:
class Country extends Model {
static entity = 'countries';
static fields () {
return {
id: this.uid(),
name: this.string(''),
users: this.hasMany(User, 'countryId'),
posts: this.hasManyThrough(Post, User, 'countryId', 'userId')
}
}
}
class User extends Model {
static entity = 'users';
static fields () {
return {
id: this.uid(),
email: this.string(''),
countryId: this.string(''),
country: this.belongsTo(Country, 'countryId'),
posts: this.hasMany(Post, 'userId'),
}
}
}
class Post extends Model {
static entity = 'posts';
static fields () {
return {
id: this.uid(),
title: this.string(''),
content: this.string(''),
userId: this.string(''),
user: this.belongsTo(User, 'userId')
}
}
}
Fetch Query for Country:
query Countries {
countries {
nodes {
id
name
}
}
}
Fetch Query for User:
query Users {
users {
nodes {
id
email
countryId
country {
id
name
}
}
}
}
Fetch Query for Post:
query Posts {
posts {
nodes {
id
title
content
user {
id
email
countryId
country {
id
name
}
}
}
}
}
# Polymorphic Relations
TIP
See the Polymorphic Relations section in the Vuex-ORM documentation.
Eager loading behaves like in a normal One To Many or One to One. So we add a eagerLoad
field to make sure the
comments are loaded automatically with the post or video.
Models:
class Post extends Model {
static entity = 'posts';
static eagerLoad = ['comments'];
static fields () {
return {
id: this.uid(),
title: this.string(''),
content: this.string(''),
comments: this.morphMany(Comment, 'commentableId', 'commentableType')
}
}
}
class Video extends Model {
static entity = 'videos';
static eagerLoad = ['comments'];
static fields () {
return {
id: this.uid(),
title: this.string(''),
url: this.string(''),
comments: this.morphMany(Comment, 'commentableId', 'commentableType')
}
}
}
class Comment extends Model {
static entity = 'comments';
static fields () {
return {
id: this.uid(),
content: this.string(''),
commentableId: this.string(''),
commentableType: this.string('')
}
}
}
Fetch Query for Post (or Video):
query Posts {
posts {
nodes {
id
title
content
comments {
nodes {
id
content
commentableId
commentableType
}
}
}
}
}
# Many To Many Polymorphic Relations
TIP
See the Many To Many Polymorphic Relations section in the Vuex-ORM documentation.
Eager loading behaves the same as in a normal Many To Many: Nothing is eager loaded automatically. So we add a
eagerLoad
field to make sure the tags are loaded automatically with the post or video.
Models:
class Post extends Model {
static entity = 'posts';
static eagerLoad = ['tags'];
static fields () {
return {
id: this.uid(),
title: this.string(''),
content: this.string(''),
tags: this.morphToMany(Tag, Taggable, 'tagId', 'taggableId', 'taggableType')
}
}
}
class Video extends Model {
static entity = 'videos';
static eagerLoad = ['tags'];
static fields () {
return {
id: this.uid(),
title: this.string(''),
url: this.string(''),
tags: this.morphToMany(Tag, Taggable, 'tagId', 'taggableId', 'taggableType')
}
}
}
class Tag extends Model {
static entity = 'tags';
static fields () {
return {
id: this.uid(),
name: this.string('')
}
}
}
class Taggable extends Model {
static entity = 'taggables';
static fields () {
return {
id: this.uid(),
tagId: this.string(''),
taggableId: this.string(''),
taggableType: this.string('')
}
}
}
Fetch Query For Post (or Video):
query Posts {
posts {
nodes {
id
title
content
tags {
nodes {
id
name
}
}
}
}
}