Skip to content

Commit c1a6671

Browse files
ryandialpadkiaking
andauthored
docs: add polymorphic one to one documentation (#92)
Co-authored-by: Kia King Ishii <[email protected]>
1 parent ba0496a commit c1a6671

File tree

3 files changed

+98
-1
lines changed

3 files changed

+98
-1
lines changed

Diff for: docs/.vuepress/config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ const sidebars = {
2525
children: [
2626
['/guide/relationships/getting-started', 'Getting Started'],
2727
['/guide/relationships/one-to-one', 'One To One'],
28-
['/guide/relationships/one-to-many', 'One To Many']
28+
['/guide/relationships/one-to-many', 'One To Many'],
29+
['/guide/relationships/polymorphic', 'Polymorphic']
2930
]
3031
},
3132
{

Diff for: docs/guide/model/decorators.md

+19
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,22 @@ class Cluster extends Model {
210210
nodes!: Node[]
211211
}
212212
```
213+
214+
### `@MorphOne`
215+
216+
Marks a property on the model as a [morphOne attribute](../relationships/polymorphic) type. For example:
217+
218+
```ts
219+
import { Model, MorphOne } from '@vuex-orm/core'
220+
import Node from '@/models/Node'
221+
222+
class Cluster extends Model {
223+
static entity = 'clusters'
224+
225+
@Attr(null)
226+
nodeIds!: number[]
227+
228+
@HasManyBy(() => Image, 'imageableId', 'imageableType')
229+
image!: Image | null
230+
}
231+
```

Diff for: docs/guide/relationships/polymorphic.md

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Relationships: Polymorphic
2+
3+
A polymorphic relationship is where a model can belong to more than one type of model on a single association.
4+
5+
## One To One
6+
7+
A one-to-one polymorphic relation is similar to a simple one-to-one relation; however, the target model can belong to
8+
more than one type of model on a single association. For example, an `Image` might be associated with a `User` or `Post`
9+
model.
10+
11+
### Defining A One To One Polymorphic Relationship
12+
13+
To define this relationship, for example, a `User` or `Post` model might be associated with one `Image`, we define a
14+
`morphOne` field to the `User` and `Post` models.
15+
16+
```js
17+
class Image extends Model {
18+
static entity = 'images'
19+
20+
static fields () {
21+
return {
22+
id: this.number(0),
23+
url: this.string(''),
24+
imageableId: this.number(0),
25+
imageableType: this.string(''),
26+
}
27+
}
28+
}
29+
30+
class User extends Model {
31+
static entity = 'users'
32+
33+
static fields () {
34+
return {
35+
id: this.number(0),
36+
name: this.string(''),
37+
image: this.morphOne(Image, 'imageableId', 'imageableType')
38+
}
39+
}
40+
}
41+
42+
class Post extends Model {
43+
static entity = 'posts'
44+
45+
static fields () {
46+
return {
47+
id: this.number(0),
48+
title: this.string(''),
49+
image: this.morphOne(Image, 'imageableId', 'imageableType')
50+
}
51+
}
52+
}
53+
```
54+
55+
The first argument passed to the `morphOne` method is the name of the model, the second argument is the name of the
56+
field which will contain the `id` of the model, and the third argument is the name of the field which will contain the
57+
`entity` of the parent model. The third argument is used to determine the "type" of the related parent model.
58+
59+
Additionally, Vuex ORM assumes that the foreign key should have a value matching the `id`
60+
(or the custom `static primaryKey`) field of the parent. In other words, Vuex ORM will look for the value of the user's
61+
`id` field in the `imageableId` field of the `Image` record. If you would like the relationship to use a value other
62+
than `id`, you may pass a fourth argument to the `morphOne` method specifying your custom key:
63+
64+
```js
65+
class User extends Model {
66+
static entity = 'users'
67+
68+
static fields () {
69+
return {
70+
id: this.number(0),
71+
userId: this.string(''),
72+
name: this.string(''),
73+
image: this.morphOne(Image, 'imageableId', 'imageableType', 'userId')
74+
}
75+
}
76+
}
77+
```

0 commit comments

Comments
 (0)