Laravel Relationships: A Beginner’s Practical Guide
Learn Laravel Eloquent relationships with a practical user-and-post example, migration steps, query tips, and ways to avoid common beginner mistakes.
Laravel Eloquent relationships let you connect related database records through clear model methods. For a beginner project, start with a one-to-many relationship: define the relationship on each model, create the database foreign key, and load related records efficiently when you need them.
Key takeaways
- Use
hasManyfor a parent that owns several records andbelongsTofor each child. - Put the foreign key on the child table, such as
posts.user_id. - Use relationship methods to create and query related records.
- Use eager loading with
withwhen showing related data in a list. - Check migrations and test both sides of the relationship.
What Laravel Eloquent relationships do
Eloquent is Laravel’s object-relational mapper, or ORM. It lets your PHP code work with database records through models, instead of writing every query by hand.
A relationship describes how records connect. For example, one user may have many posts, while each post belongs to one user. Once you define these connections, Laravel can retrieve related data and build queries through readable model methods.
This guide uses a simple users-and-posts example. The same pattern works for other parent-and-child data, such as a shop with products or a project with tasks. For a broader view of Laravel development options, see Laravel Development.
Choose the relationship that matches your data
Before writing code, describe the connection in plain language. Ask how many records can exist on each side. The answer helps you choose the right relationship type.
- One to one: one user has one profile.
- One to many: one user has many posts.
- Many to many: many posts can have many tags.
For this example, a user can publish several posts, but each post has one author. That is a one-to-many relationship from the user’s perspective and a many-to-one relationship from the post’s perspective.
Laravel documents common relationship types, including one-to-one, one-to-many, and many-to-many. Use the type that reflects your actual data, not just the first method that seems to work.
Build a one-to-many relationship
Start by creating the models and migrations. Artisan can generate both in one command:
php artisan make:model Post -mThe -m option also creates a migration file. In the posts migration, add a foreign key that points to the users table:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('title');
$table->text('body');
$table->timestamps();
});The user_id field stores the author’s user ID. The constraint tells the database that each value must refer to an existing user. The delete rule shown here removes a user’s posts when that user is deleted, so choose it only if that behavior fits your project.
Next, define the parent relationship in app/Models/User.php:
use Illuminate\Database\Eloquent\Relations\HasMany;
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}Then define the inverse relationship in app/Models/Post.php:
use Illuminate\Database\Eloquent\Relations\BelongsTo;
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}By convention, Laravel matches the posts relationship with the user_id foreign key. If your table or key uses a different name, you can pass that name to the relationship method. See the official Eloquent relationships documentation for supported options.
Create and retrieve related records
After the relationship exists, you can use it to create a post for a specific user. This keeps the connection clear in your application code:
$user = User::findOrFail(1);
$post = $user->posts()->create([
'title' => 'My first Laravel post',
'body' => 'A short example post.',
]);The create method inserts the post and sets its user_id automatically. Make sure the model allows these attributes for mass assignment, or assign values individually. Laravel’s Eloquent documentation explains model creation and attribute protection.
You can also retrieve a user’s posts through the relationship:
$posts = $user->posts;
$author = $post->user;Notice the difference between posts() and posts. The method form returns a relationship query, so you can add filters or create records. The property form retrieves the related data. Use a query when you need limits or conditions, such as $user->posts()->latest()->get().
Load relationships efficiently
A common beginner mistake is loading each author separately while displaying a list of posts. If a page shows many posts, repeated database queries can slow it down. This pattern is often called the N+1 query problem: one query loads the list, then extra queries load each related author.
Use eager loading to ask Eloquent to retrieve the posts and their authors together:
$posts = Post::with('user')
->latest()
->get();You can then access each post’s author in a loop:
foreach ($posts as $post) {
echo $post->title;
echo $post->user->name;
}For a list of users and their posts, load the other direction with User::with('posts')->get(). Eager load only the relationships the page needs. This keeps code easy to follow and avoids fetching unrelated data.
Test the relationship and avoid common mistakes
Run your migration in a local or test database before relying on the relationship:
php artisan migrateThen check that a user can retrieve their posts and that a post can retrieve its author. A simple feature test can create both records and verify the relationship. If your project already uses model factories, those can help create test data consistently.
When something does not work, check these common issues:
- Missing foreign key: the child table needs the correct key, such as
user_id. - Wrong model namespace: confirm that the related model is imported or referenced correctly.
- Method and property confusion: use
posts()to build a query andpoststo access loaded results. - Unintended delete behavior: choose a database delete rule that matches your data-retention needs.
- Too many queries: eager load relationships used in repeated lists.
Keep relationship methods focused on how records connect. Add filters when they describe a useful subset, and keep application-specific decisions in the part of the code responsible for that behavior. If you are planning a larger system, custom web application development can help shape its data structure and workflows.
Frequently asked questions
Where should I define an Eloquent relationship?
Define it as a method on the model that represents that side of the connection. For example, put posts() on User and user() on Post.
Which model gets the foreign key?
For a one-to-many relationship, the child table stores the foreign key. In this example, each post stores its author’s ID in user_id.
What is the difference between posts and posts()?
posts() gives you a relationship query that you can filter or use to create records. posts accesses the related collection of models.
When should I use eager loading?
Use eager loading when you know a page will access a relationship for several records, such as showing the author beside every post in a list.
Can Laravel support relationships beyond one-to-many?
Yes. Eloquent supports several relationship types, including one-to-one and many-to-many. Choose the type that fits how your records are connected.
Start with one clear relationship, then build on it as your project grows. If you need help planning or building a Laravel application, contact Herby Design to discuss your project.
Found this helpful? Share it
Need help with your website?
I build fast, SEO-ready websites and web applications.