Laravel 9 One To Many | HasMany Eloquent Relationship Tutorial (ok)

https://www.laravelia.com/post/laravel-9-one-to-manyhasmany-eloquent-relationship-tutorial

Category : #laravel

C:\xampp\htdocs\songkhoe\database\seeders\DatabaseSeeder.php

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Post;
use App\Models\Comment;
class DatabaseSeeder extends Seeder
{
  /**
   * Seed the application's database.
   *
   * @return void
   */
  public function run()
  {
    // User::factory(10)->create();
    Post::factory(10)->create();
    Comment::factory(10)->create();
  }
}

C:\xampp\htdocs\songkhoe\database\factories\CommentFactory.php

<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\Comment;
class CommentFactory extends Factory
{
  protected $model = Comment::class;
  /**
   * Define the model's default state.
   *
   * @return array
   */
  public function definition()
  {
    return [
      "post_id" => $this->faker->numberBetween(1, 10),
      "comment" => $this->faker->text(150)
    ];
  }
}

C:\xampp\htdocs\songkhoe\database\factories\PostFactory.php

<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\Post;
class PostFactory extends Factory
{
  protected $model = Post::class;
  /**
   * Define the model's default state.
   *
   * @return array
   */
  public function definition()
  {
    return [
      "name" => $this->faker->userName()
    ];
  }
}

C:\xampp\htdocs\songkhoe\database\migrations\2022_11_18_021539_create_posts_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('posts', function (Blueprint $table) {
      $table->increments('id');
      $table->string("name");
    });
  }
  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::dropIfExists('posts');
  }
}

C:\xampp\htdocs\songkhoe\database\migrations\2022_11_18_022236_create_comments_table.php

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

class CreateCommentsTable extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('comments', function (Blueprint $table) {
      $table->increments('id');
      $table->integer('post_id')->unsigned();
      $table->string("comment");
      $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::dropIfExists('comments');
  }
}

C:\xampp\htdocs\songkhoe\app\Models\Post.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
  use HasFactory;
  public $timestamps = false;
  protected $fillable = [
    'name'
  ];
  /**
   * Get the comments for the blog post.
   */
  public function comments()
  {
    return $this->hasMany(Comment::class);
  }
}

C:\xampp\htdocs\songkhoe\app\Models\Comment.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
  use HasFactory;
  protected $fillable = [
    'post_id',
    'comment'
  ];
  /**
   * Get the post that owns the comment.
   */
  public function post()
  {
    return $this->belongsTo(Post::class,'id');
  }
}

C:\xampp\htdocs\songkhoe\app\Http\Controllers\TestController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Comment;
class TestController extends Controller
{
  public function index($id)
  {
      $comments = Post::find($id)->comments;
      foreach ($comments as $comment) {
        echo '<pre>';
        var_export($comment->comment);
        echo '<pre>';
      }
  }
  public function index2($id)
  {
      $post = Comment::find($id)->post;
      echo '<pre>';
        echo "id and name => " . $post->id . " and " . $post->name;
      echo '<pre>';
  }
}

C:\xampp\htdocs\songkhoe\routes\web.php


<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TestController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
  return view('welcome');
});
Route::get('/test/{id}', [TestController::class, 'index']);
Route::get('/test2/{id}', [TestController::class, 'index2']);
Route::get('/save/{id}', [TestController::class,'save']);

Tags : #laravel, #laravel eloquent relationship

In a relational database management system, we know database tables are related to one another. For example, a post may have many comments or an order could be related to the user who placed it. Laravel eloquent makes managing and working with these relationships very convenient. Laravel provides many relationships and in this tutorial, I will show you how we handle one to many or we can call this hasMany eloquent relationship.

In this Laravel 9 one to many relationship example tutorial, I am going to use the Post and Comments concept. Suppose, A post may have many comments and a comment may be related to one post. Let's see how we can define Laravel's one to many relationship.

We can use the hasMany() method to define one to many relationships and the first argument passed to the hasMany method is the name of the related model class. In this example, I will create a posts table and a comments table. Now I will create one to many relationships with each other by using the Laravel Eloquent Model.

Now assume we have a table like below:

posts table:

Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->string("name");
    $table->timestamps();
});

PHPCopy

comments table:

Schema::create('comments', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('post_id')->unsigned();
    $table->string("comment");
    $table->timestamps();
    $table->foreign('post_id')->references('id')->on('posts')
        ->onDelete('cascade');
});

PHPCopy

Defining One To Many Relationship

Our table is ready, now we can define one to many or hasmany eloquent relationship by the following way:

app\Models\Post.php

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Post extends Model
{
    /**
     * Get the comments for the blog post.
     */
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

PHPCopy

If we avoid foreign like above, then remember Laravel Eloquent will assume the foreign key column on the Comment model is post_id. Now we can find every comment of a single post like:

App\Http\Controllers\TestController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index($id)
    {   
        $comments = Post::find($id)->comments;

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

PHPCopy

Defining Inverse Relationship of hasMany

Now we know how to define hasMany or one to many relationships. Now we will see how we can define the inverse relationship of hasMany. Let's define a relationship on the Comment model that will let us access the post. We can define the inverse of a hasMany relationship using the belongsTo method like:

app/Models/Comment.php

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Comment extends Model
{
    /**
     * Get the post that owns the comment.
     */
    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

PHPCopy

Read also: Laravel One To One/HasOne Eloquent Relationship Tutorial

Here we can also pass fereign_key and local_key like below:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Comment extends Model
{
    /**
     * Get the post that owns the comment.
     */
    public function post()
    {
        return $this->belongsTo(Post::class,'foreign_key', 'owner_key');
    }
}

PHPCopy

Now we can also fetch post like:

App\Http\Controllers\TestController.php

<?php

namespace App\Http\Controllers;

use App\Models\Comment;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index($id)
    {   
        $comment = Comment::find($id);
        return $comment->post->title;
    }
}

PHPCopy

Read also: Complete Explanation With Example On Laravel Middleware

Conclusion

Now we can know laravel 9 one to may relationship and how it works. Hope this Laravel 9 hasMany relationship tutorials will help you.

Last updated