Relationships

Define how models relate with hasMany, belongsTo and more.

Syntaxpublic function posts() { return $this->hasMany(Post::class); }

Eloquent models can describe how tables relate. Define a method that returns a relationship type:

  • hasMany() — one user has many posts.
  • belongsTo() — a post belongs to a user.
  • belongsToMany() — many-to-many.

Access them like properties: $user->posts.

Example

Example · php
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

// Usage:
// $user->posts;  // a Collection of the user's posts

When to use it

  • A blog's Post model defines hasMany('App\Models\Comment') so $post->comments returns all related Comment records without writing a JOIN.
  • An e-commerce Order model uses belongsToMany('App\Models\Product') with a pivot table so each order can contain many products and each product can appear in many orders.
  • A user profile uses hasOne('App\Models\Profile') to ensure a one-to-one relationship and access $user->profile->bio directly.

More examples

hasMany and belongsTo

Defines both sides of a one-to-many relationship: a Post has many Comments, and each Comment belongs to a Post.

Example · php
// app/Models/Post.php
public function comments(): HasMany
{
    return $this->hasMany(Comment::class);
}

// app/Models/Comment.php
public function post(): BelongsTo
{
    return $this->belongsTo(Post::class);
}

// Usage
$comments = $post->comments;     // Collection of Comment models
$parent   = $comment->post;      // The Post model

belongsToMany with pivot

Declares a many-to-many relationship using an order_product pivot table, exposing qty and unit_price as pivot attributes.

Example · php
// app/Models/Order.php
public function products(): BelongsToMany
{
    return $this->belongsToMany(Product::class)
                ->withPivot('qty', 'unit_price')
                ->withTimestamps();
}

// Attach a product with pivot data
$order->products()->attach($productId, ['qty' => 2, 'unit_price' => 49.99]);

// Sync (detaches any not in the array)
$order->products()->sync([$id1, $id2]);

Eager loading to prevent N+1

with() eager loads the author and tags relationships in just two queries, eliminating the N+1 problem that lazy loading causes.

Example · php
// N+1 problem: 1 query for posts + N queries for each author
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name; // extra query per post
}

// Eager loading: 2 queries total
$posts = Post::with('author', 'tags')->get();
foreach ($posts as $post) {
    echo $post->author->name; // no extra query
}

Discussion

  • Be the first to comment on this lesson.