# Polymorphic Relationships

Just like in Laravel, you can define Polymorphic Relationships (opens new window) in your schema.

# One to One

Suppose you have defined a model structure just like the Laravel example docs. You have two models, Post and User which may both have an Image assigned.

Let's start off with the plain type definitions, without any relations.

type Post {
  id: ID!
  title: String!
}

type User {
  id: ID!
  name: String!
}

type Image {
  id: ID!
  url: String!
}

First, let's go ahead and add the relations to Image since they are straightforward. The field name should match your relationship method name and be annotated with the @morphOne directive.

type Post {
  id: ID!
  title: String!
  image: Image! @morphOne
}

type User {
  id: ID!
  name: String!
  image: Image @morphOne
}

Depending on the rules of your application, you might require the relationship to be there in some cases, while allowing it to be absent in others. In this example, a Post must always have an Image, while a User does not require one.

For the inverse, you will need to define a union type to express that an Image might be linked to different models.

union Imageable = Post | User

Now, reference the union type from a field in your Image type. You can use the @morphTo directive for performance optimization.

type Image {
  id: ID!
  url: String!
  imageable: Imageable! @morphTo
}

The default type resolver will be able to determine which concrete object type is returned when dealing with Eloquent models, so your definition should just work.

Given you have a field images that returns a list of [Image!]!, you could query it like this:

{
  images {
    imageable {
      __typename
      ... on Post {
        title
      }
      ... on User {
        name
      }
    }
  }
}

# One to Many

Based on the above example, you could change your application to allow for a Post to have many images attached to it. The field images now returns a list of Image object and is annotated with the @morphMany directive.

type Post {
  id: ID!
  title: String!
  images: [Image]! @morphMany
}

type Image {
  id: ID!
  url: String!
  imageable: Imageable! @morphTo
}

union Imageable = Post | User