# Eloquent Relationships
Just like in Laravel, you can define Eloquent Relationships (opens new window) in your schema.
Suppose you have defined the following model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
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
tofalse
.
# 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
}
# 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:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Post extends Model
{
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}