|
| 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