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: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: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:Polymorphic Relationships
A polymorphic relationship allows one model to belong to multiple other model types. Every model involved must callstatic { 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: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:Strict Loading
EnablestrictLoading 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:
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
Creating Related Records
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’supdated_at. Useful for cache invalidation — if a comment is added to a post, the post itself looks “recently updated”:
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
Circular Dependency Error
Circular Dependency Error
Problem: Models importing each other cause circular dependenciesSolution: Use string references instead of imports
Relationship Returns Undefined
Relationship Returns Undefined
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
N+1 Query Problem
N+1 Query Problem
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
