Skip to main content

What are Relationships?

Relationships define how different pieces of data connect to each other. Think of them as the connections between tables in your database.
Real-world analogy: In a blog system:
  • A User writes many Posts (one-to-many)
  • A Post belongs to one User (belongs-to)
  • A Post can have many Tags, and Tags can be on many Posts (many-to-many)

One-to-One Relationships

A one-to-one relationship means one record in a table is associated with exactly one record in another table. Think of it like a person and their passport - each person has one passport, and each passport belongs to one person.

Example: User has one Profile

Migration for users table:
Migration for profiles table:
Model definitions:
String References: Always use string model names ('Profile') instead of importing classes to avoid circular dependencies.

One-to-Many Relationships

A one-to-many relationship means one record can be associated with multiple records in another table. Think of it like a blog author and their posts - one author can write many posts, but each post belongs to only one author.

Example: User has many Posts

Migration for posts table:
Model definitions:

Many-to-Many Relationships

A many-to-many relationship means multiple records in one table can be associated with multiple records in another table. Think of it like blog posts and tags - one post can have many tags, and one tag can be used on many posts. This requires a “pivot” or “junction” table to store the connections.

Example: Posts have many Tags

Migration for tags table:
Migration for pivot table:
Model definitions:

Polymorphic Relationships

A polymorphic relationship allows one model to belong to multiple other model types. Every model involved must call static { this.register(); } so the ORM can resolve type strings at runtime.

morphOne — One-to-one polymorphic

morphMany — One-to-many polymorphic

Example: Comments on Posts and Videos

Migration for videos table:
Migration for comments table:
Model definitions:

Has-Many-Through

A has-many-through relationship provides a shortcut to access distant relationships through an intermediate model. Think of it like getting all posts from a specific country - you go through users to get to their posts, but you want to skip the middle step.

Example: Country has many Posts through Users

Migration for countries table:
Update users table migration:
Model definitions:

Strict Loading

Enable strictLoading on a model to throw an error whenever a relation is accessed without being eager loaded. This catches N+1 problems at development time instead of silently returning undefined:
Enable strictLoading during development to catch N+1 issues early, then remove or leave it enabled based on your team’s preference.

Eager Loading

Load relationships efficiently to avoid N+1 queries.

Basic Eager Loading

Multiple Relationships

Nested Relationships

Conditional Eager Loading

Lazy Loading

Load relationships on-demand after the model is retrieved.

Working with Relationships

Many-to-Many Operations

Querying Relationships

Relationship Constraints

Has Constraint

Find records that have related records:

Doesn’t Have Constraint

Advanced Relationship Patterns

Self-Referencing Relationships

Conditional Relationships

Custom Foreign Keys

Touch

When a child record saves, automatically bump the parent’s updated_at. Useful for cache invalidation — if a comment is added to a post, the post itself looks “recently updated”:
You can touch multiple parents at once:
Only belongsTo relations are supported for touches. The parent must have timestamps enabled.

Performance Tips

1. Use Eager Loading

2. Select Only Needed Columns

3. Use Constraints in Eager Loading

4. Count Instead of Loading

Common Relationship Patterns

Blog System

E-commerce System

Troubleshooting

Problem: Models importing each other cause circular dependenciesSolution: Use string references instead of imports
Problem: Relationship method returns undefinedSolutions:
  • Check foreign key names match your database
  • Ensure related model is registered for polymorphic relationships
  • Verify table and column names are correct
Problem: Too many database queries when accessing relationshipsSolution: Use eager loading with with()

Next Steps

Database Migrations

Learn to create and modify database tables

Advanced Features

Explore events, observers, and custom casting