Laravel

Laravel Eloquent One To Many Relationships

Laravel Eloquent One To Many Relationships
Written by ProgrammingPot

After learning about Laravel Eloquent One To One Tutorial, In this tutorial we are going to learn about the Laravel Eloquent One To Many Relationships. A “one-to-many” relationship is used to define relationships where a single model owns any amount of other models. For example, a blog post may have an infinite number of comments. Like all other Eloquent relationships, one-to-many relationships are defined by placing a function on your Eloquent model:

Laravel Eloquent One To Many Relationships


Example

We are defining the one to one relationship with Post and Comment. So first we need to set their schema.

Step 1: Make one schema for account details.

Go to the terminal and type the following command.

php artisan make:migration create_comments_table
php artisan make:migration create_posts_table

So, it will create one schema file in which, we need to define the columns like the following.

Post Table Schema

<?php
// create_posts_table
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('slug')->unique();
            $table->string('status');
            $table->integer('user_id');
            $table->integer('category_id');
            $table->integer('view');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Comment Table Scheme

<?php
// create_comments_table
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCommentTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->string('website');
            $table->string('email');
            $table->text('text');
            $table->integer('post_id');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('comments');
    }
}

Step 2: Migrate the Table or Create Table

Next, type the following command for migrate the both table and its relationship.

php artisan migrate

It will create all tables in the database.

Step 3: Make the Post.php Model

Make one model called Comment.php and Post.php by typing this command.

php artisan make:model Comment
php artisan make:model Post

Then your Comment.php model looks like,

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    //
}

and the Post.php model looks like

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

Step 4: Defining Laravel Eloquent One To Many Relationships

Now, In Post.php Model, write the following function to define the relationship with the Comment model.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * Get the comments for the blog post.
     */
    public function comments()
    {
        return $this->hasMany('App\Comment');
    }
}

Remember, Eloquent will automatically determine the proper foreign key column on the Comment model. By convention, Eloquent will take the “snake case” name of the owning model and suffix it with _id. So, for this example, Eloquent will assume the foreign key on the Comment model is post_id.

Once the relationship has been defined, we can access the collection of comments by accessing the comments property. Remember, since Eloquent provides “dynamic properties”, we can access relationship methods as if they were defined as properties on the model:

$comments = App\Post::find(1)->comments;

foreach ($comments as $comment) {
    //
}

Of course, since all relationships also serve as query builders, you can add further constraints to which comments are retrieved by calling the comments method and continuing to chain conditions onto the query:

$comment = App\Post::find(1)->comments()->where('title', 'foo')->first();

Like the hasOne method, you may also override the foreign and local keys by passing additional arguments to the hasMany method:

return $this->hasMany('App\Comment', 'foreign_key');

return $this->hasMany('App\Comment', 'foreign_key', 'local_key');

Step:5 An Inverse Of The Relationship.

Now that we can access all of a post’s comments, let’s define a relationship to allow a comment to access its parent post. To define the inverse of a hasMany relationship, define a relationship function on the child model which calls the belongsTo method:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    /**
     * Get the post that owns the comment.
     */
    public function post()
    {
        return $this->belongsTo('App\Post');
    }
}

Once the relationship has been defined, we can retrieve the Post model for a Comment by accessing the post “dynamic property”:

$comment = App\Comment::find(1);

echo $comment->post->title;

In the example above, Eloquent will try to match the post_id from the Comment model to an id on the Post model. Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with _id. However, if the foreign key on the Comment model is not post_id, you may pass a custom key name as the second argument to the belongsTo method:

/**
 * Get the post that owns the comment.
 */
public function post()
{
    return $this->belongsTo('App\Post', 'foreign_key');
}

If your parent model does not use id as its primary key, or you wish to join the child model to a different column, you may pass a third argument to the belongsTo method specifying your parent table’s custom key:

/**
 * Get the post that owns the comment.
 */
public function post()
{
    return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
}

Finally, our tutorial on Laravel Eloquent One To Many Relationships is over. Happy Coding.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.