Using belongsTo() and hasMany() in Laravel Eloquent

Updated: January 18, 2024 By: Guest Contributor Post a comment

Introduction

Laravel Eloquent provides an elegant, easy-to-understand, and active record implementation for working with your database. It allows web developers to interact with their database tables and relationships using expressive syntax. In this tutorial, we’ll explore how to use two of the most important relationship methods provided by Eloquent: belongsTo() and hasMany().

Relationships defined in Eloquent allow for the easy retrieval and management of related models. Before we deep dive into these methods, it’s crucial to understand that belongsTo() is used within the model that represents the table with the foreign key, while hasMany() is used in the model representing the table that contains the primary key referred to by the foreign key.

Understanding One-to-Many Relationships

In a one-to-many relationship, a single model can be associated with multiple models. For example, suppose we have two database tables, authors and books, where an author can have multiple books but a book can only belong to one author. Here, authors is the primary model containing the primary key, and books is the related model containing the foreign key.

Defining hasMany()

class Author extends Model
{
    public function books()
    {
        return $this->hasMany(Book::class);
    }
}

The above code snippet in the Author model creates a relationship method named books(). This method defines that an author can have many books. Now, you can retrieve all books for an author by accessing this method as a dynamic property:

$author = Author::find(1);
$books = $author->books;

Defining belongsTo()

class Book extends Model
{
    public function author()
    {
        return $this->belongsTo(Author::class);
    }
}

In this code snippet, the Book model defines a method called author() that sets up the inverse of the hasMany relationship. With this method, we can find the author of a book:

$book = Book::find(1);
$author = $book->author;

Implementing Relationships

To effectively utilize these relationship methods, necessary database migrations should set up the correct foreign key constraints. Here’s an example of what those migration files might include:

// Migration for the 'authors' table
Schema::create('authors', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    // Other author columns...
    $table->timestamps();
});

// Migration for the 'books' table
Schema::create('books', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('author_id');
    $table->string('title');
    // Other book columns...
    $table->timestamps();

    $table->foreign('author_id')->references('id')->on('authors')->onDelete('cascade');
});

This migration creates the necessary tables and foreign key constraint for the author-book relationship. Now, we can interact with the related models fluently.

Retrieving Related Models

Now that the relationships are set up, you can use the Eloquent’s dynamic properties or the get() method to access related models. Here are a few examples:

// Get all books of the first author
$author = Author::with('books')->first();
$books = $author->books;

// Get the author of the first book
$book = Book::with('author')->first();
$author = $book->author;

// Adding constraints to a relationship query
$authorBooks = $author->books()->where('published', 1)->get();

Inserting and Updating Related Models

Laravel makes it just as easy to insert and update related models. When inserting new books for an author, we can use the create() method provided by the hasMany() relationship:

$author = Author::find(1);
$book = $author->books()->create(['title' => 'New Book Title']);

When you need to attach a book to an author that already exists, you can use the associate() method within the belongsTo() relationship:

$author = Author::find(1);
$book = new Book(['title' => 'Another Book Title']);
$book->author()->associate($author);
$book->save();

Similarly, you can disassociate or remove an existing relationship using the dissociate() method:

$book->author()->dissociate();
$book->save();

Conclusion

In this tutorial, we’ve covered the basics of setting up and utilizing one-to-many relationships using Laravel Eloquent’s belongsTo() and hasMany() methods. By understanding these relations, you can write more efficient, readable code when handling database operations related to your application’s models.

We explored how to define and implement Eloquent relationships, retrieve related models, and insert or update models within these relationships. Remember that Eloquent relationships are here to simplify the way you write database queries, making your codebase cleaner and your development process quicker and more enjoyable.

Eloquent offers a wealth of additional relationship types and methods, such as hasOne(), belongsToMany(), and morphToMany(), among others. As you become more comfortable with these relationships, I encourage you to explore the Eloquent documentation to further expand your understanding of what’s possible with Laravel’s ORM.