# Eloquent Relationships

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

Suppose you have defined the following model:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

final class Post extends Model
{
    public function comments(): HasMany
    {
        return $this->hasMany(Comment::class);
    }

    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

Just add fields to your type that are named just like the relationships:

type Post {
  author: User
  comments: [Comment!]
}

Because Laravel relationships can be accessed just like regular properties on your model, the default field resolver will work just fine.

# Avoiding the N+1 performance problem

When accessing Eloquent relationships as properties, the relationship data is "lazy loaded". This means the relationship data is not actually loaded until you first access the property.

This leads to a common performance pitfall that comes with the nested nature of GraphQL queries: the so-called N+1 query problem. Learn more.

When you decorate your relationship fields with Lighthouse's built-in relationship directives, queries are automatically combined through a technique called batch loading. That means you get fewer database requests and better performance without doing much work.

Batch loading might not provide ideal performance for all use cases. You can turn it off by setting the config option batchload_relations to false.

# One To One

Use the @hasOne directive to define a one-to-one relationship (opens new window) between two types in your schema.

type User {
  phone: Phone @hasOne
}

The inverse can be defined through the @belongsTo directive.

type Phone {
  user: User @belongsTo
}

# One To Many

Use the @hasMany directive to define a one-to-many relationship (opens new window).

type Post {
  comments: [Comment!]! @hasMany
}

Again, the inverse is defined with the @belongsTo directive.

type Comment {
  post: Post! @belongsTo
}

# Many To Many

While many-to-many relationships (opens new window) are a bit more work to set up in Laravel, defining them in Lighthouse is a breeze. Use the @belongsToMany directive to define it.

type User {
  roles: [Role!]! @belongsToMany
}

The inverse works the same.

type Role {
  users: [User!]! @belongsToMany
}

# Has One Through

Use the @hasOneThrough directive to define a has-one-through relationship (opens new window).

type Mechanic {
  carOwner: Owner! @hasOneThrough
}

# Has Many Through

Use the @hasManyThrough directive to define a has-many-through relationship (opens new window).

type Project {
  deployments: [Deployment!]! @hasManyThrough
}

# Renaming relations

When you define a relation, Lighthouse assumes that the field and the relationship method have the same name. If you need to name your field differently, you have to specify the name of the method.

type Post {
  author: User! @belongsTo(relation: "user")
}

This would work for the following model:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

final class Post extends Model
{
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}