---
description: >-
  https://www.itsolutionstuff.com/post/laravel-9-one-to-many-eloquent-relationship-tutorialexample.html
---

# Laravel 9 One to Many Eloquent Relationship Tutorial (ok)

> Chú ý phần này quan trọng là chúng ta xóa và cập nhập mối quan hệ :)\
> Khi loại bỏ `belongsTo` relationship, bạn có thể sử dụng `dissociate` method. Method này sẽ thiết lập các foreign key thành `null`. đọc thêm về xóa ở dưới

## Ví dụ 1

Lấy code giống của ví dụ 1 phần [One To One](laravel-9-one-to-one-relationship-example-ok) chỉ thay đổi chỗ phương thức&#x20;

app\Models\User.php

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FG9d4P4KR9o4I88FOaUcc%2FScreenshot_5.png?alt=media&#x26;token=2d407346-6111-4bd8-8b3a-6c7f347ac5a1" alt=""><figcaption></figcaption></figure>

```php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable {
  use HasApiTokens, HasFactory, Notifiable;
  /**
   * The attributes that are mass assignable.
   *
   * @var array<int, string>
   */
  protected $fillable = [
    'name',
    'email',
    'password',
  ];
  /**
   * The attributes that should be hidden for serialization.
   *
   * @var array<int, string>
   */
  protected $hidden = [
    'password',
    'remember_token',
  ];
  /**
   * The attributes that should be cast.
   *
   * @var array<string, string>
   */
  protected $casts = [
    'email_verified_at' => 'datetime',
  ];
  public function phone() {
    // return $this->hasOne(Phone::class);
    return $this->hasMany(Phone::class);
  }
}
```

> Ta nhận thấy nếu dùng phương thức **hasMany** thay cho **hasOne** kết quả trả về là một mảng. Nếu không dùng như chúng ta biết nó chỉ lấy 1 giá trị gần nhất sắp xếp theo thứ tự giảm dần (des)im

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FIuaVLNZ2iSHe5yfmm0Zn%2FScreenshot_1.png?alt=media&#x26;token=769b6e55-0d22-4e63-83af-aa111f5df16d" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FPxMjYJ1JBiD6BGX5gJ0m%2FScreenshot_2.png?alt=media&#x26;token=d2f17708-08eb-47b5-9298-de2add37f83c" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FIwYvT18j7lOlzUu9eZBC%2FScreenshot_3.png?alt=media&#x26;token=b7f21bc5-37a7-4a88-8531-b4db2b4ef0c1" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FEP5QHuvXLmMlSBIrAyu9%2FScreenshot_4.png?alt=media&#x26;token=80e5af64-7689-41db-9ea8-0ae7a986c91d" alt=""><figcaption></figcaption></figure>

_**Ví dụ 2:**_

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

```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)
    ];
  }
}p
```

C:\xampp\htdocs\datvietcoconut\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\datvietcoconut\database\migrations\2022\_11\_18\_021539\_create\_posts\_table.php

```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\datvietcoconut\database\migrations\2022\_11\_18\_022236\_create\_comments\_table.php

```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\datvietcoconut\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\datvietcoconut\app\Models\Comment.php

```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\datvietcoconut\app\Http\Controllers\TestController.php

```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>';
  }
  public function save($id)
  {
    $post = Post::find($id);
    $comment1 = new Comment();
    $comment1->comment = "Hi ItSolutionStuff.com Comment 1";
    $comment2 = new Comment();
    $comment2->comment = "Hi ItSolutionStuff.com Comment 2";
    $post = $post->comments()->saveMany([$comment1, $comment2]);
  }
  public function create($id)
  {
    $post = Post::find($id);
    $comment = new Comment();
    $comment->comment = "Hi ItSolutionStuff.com Update ID 6";
    $post = $post->comments()->save($comment);
  }
  public function associate($idcomment, $idpost)
  {
    $comment = Comment::find($idcomment);
    $post = Post::find($idpost);
    $comment->post()->associate($post)->save();
  }
}

```

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

```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']);
Route::get('/create/{id}', [TestController::class,'create']);
Route::get('/associate/{idcom}/{idpost}', [TestController::class,'associate']);

```

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2Ffyg1gZsLT9Q2D5GwOiSn%2Fimage.png?alt=media&#x26;token=aa1b3680-2e51-4234-a3ce-0322ce21b4ef" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FMIGzo4BkoDDfZST78AM7%2Fimage.png?alt=media&#x26;token=f409708a-6c5a-45be-ab7d-2170cbaee8dd" alt=""><figcaption></figcaption></figure>

Thêm

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FeYvaC1ahVw8TlKY98l3j%2Fimage.png?alt=media&#x26;token=4a57b370-7b42-4d8a-8192-54148410a7a9" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FK4zJEUs6l30hFlATeORz%2FScreenshot_1.png?alt=media&#x26;token=7296468d-0e5f-4a0a-a2ee-0522f4499ba5" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FnbpvbpACkK2exkkVkpfB%2FScreenshot_2.png?alt=media&#x26;token=6e07f96e-5ffe-4b83-8bb2-f8ac59c40b98" alt=""><figcaption></figcaption></figure>



<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2F4H381RuGp9XU65mnZTFy%2FScreenshot_4.png?alt=media&#x26;token=43b45675-5074-4ac1-8b02-53d34e8cb8d2" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FzbsvXdqSq1CBRKXevbuV%2FScreenshot_5.png?alt=media&#x26;token=8c40424b-62c0-4780-925d-d4ebd163843b" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FzbsvXdqSq1CBRKXevbuV%2FScreenshot_5.png?alt=media&#x26;token=8c40424b-62c0-4780-925d-d4ebd163843b" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FqdSTYt7yyAtTFBPckLhd%2FScreenshot_6.png?alt=media&#x26;token=a111f18d-4853-46ad-80d6-ac92f207f7d3" alt=""><figcaption></figcaption></figure>

## Phải rất chú ý đến điều này :(

> Lúc trước điền sai key :(
>
> ```php
> public function post()
>   {
>     return $this->belongsTo(Post::class,'id');
>   }
> ```
>
> Giờ phải chuyển về thế này&#x20;
>
> ```php
> public function post()
>   {
>     return $this->belongsTo(Post::class,'post_id');
>   }
> ```
>
>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FVJX1uQr4SeA8FYuW9WaQ%2Fimage.png?alt=media&#x26;token=1ba5708a-ecc4-4afd-9e5e-d1ad1f41211a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FQQpUvRO7aW5KVbY90GQM%2Fimage.png?alt=media&#x26;token=1bb41dfa-8052-442f-90dc-e41fd9848e26" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1957079826-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MCBeDUD-PK_RF-YgJRe%2Fuploads%2FXqAUCcxDU87zkpwemoNF%2Fimage.png?alt=media&#x26;token=77a9f46d-5999-4985-93ef-1268b695abf8" alt=""><figcaption></figcaption></figure>



_**Tham khảo Source code:**_ [_**https://app.gitbook.com/o/-LVfVRgJVnpA6bttpEFT/s/-MCBeDUD-PK\_RF-YgJRe/laravel-9-many-to-many-eloquent-relationship-tutorial**_](laravel-9-many-to-many-eloquent-relationship-tutorial-full-ok)

## Laravel 9 One to Many Eloquent Relationship Tutorial

By Hardik Savani March 25, 2022 Category : Laravel![](https://a.vdo.ai/core/assets/img/cross.svg)PlayUnmuteLoaded: 1.00%Fullscreen[![VDO.AI](https://a.vdo.ai/core/assets/img/logo.svg)](https://vdo.ai/?utm_medium=video\&utm_term=itsolutionstuff.com\&utm_source=vdoai_logo)

Hi Dev,

Here, I will show you laravel 9 one to many relationship examples. it's a simple example of laravel 9 hasmany relationship examples. step by step explain has many relationship laravel 9. This tutorial will give you a simple example of laravel 9 one to many sync. Alright, let’s dive into the steps.

So in this tutorial, you can understand how to create migration with a foreign key schema for one to many relationships, use sync with a pivot table, create records, get all data, delete, update, and everything related to one to many relationships.

In this example, I will create a "posts" table and a "comments" table. both tables are connected with each other. now we will create one to many relationships with each other by using the laravel Eloquent Model. We will first create database migration, then model, retrieve records, and then how to create records too. So you can also see the database table structure on the below screen.

![](https://www.itsolutionstuff.com/upload/laravel-9-one-many-relation.png)

One to Many Relationship will use "hasMany()" and "belongsTo()" for relation.

**Create Migrations:**

Now we have to create migration of "posts" and "comments" table. we will also add foreign key with posts table. so let's create like as below:

posts table migration:

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

comments table migration:

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

**Create Models:**

Here, we will create Post and Comment table model. we will also use "hasMany()" and "belongsTo()" for relationship of both model.

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;     /**     * Get the comments for the blog post.     *        * Syntax: return $this->hasMany(Comment::class, 'foreign_key', 'local_key');     *     * Example: return $this->hasMany(Comment::class, 'post_id', 'id');     *      */    public function comments()    {        return $this->hasMany(Comment::class);    }}
```

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;      /**     * Get the post that owns the comment.     *       * Syntax: return $this->belongsTo(Post::class, 'foreign_key', 'owner_key');     *     * Example: return $this->belongsTo(Post::class, 'post_id', 'id');     *      */    public function post()    {        return $this->belongsTo(Post::class);    }}
```

**Retrieve Records:**

```
<?php  namespace App\Http\Controllers;  use Illuminate\Http\Request;use App\Models\Post;  class PostController extends Controller{    /**     * Write code on Method     *     * @return response()     */    public function index(Request $request)    {        $comments = Post::find(1)->comments;          dd($comments);    }}
```

```
<?php namespace App\Http\Controllers;  use Illuminate\Http\Request;use App\Models\Comment;  class PostController extends Controller{    /**     * Write code on Method     *     * @return response()     */    public function index(Request $request)    {        $post = Comment::find(1)->post;          dd($post);    }}
```

**Create Records:**

```
<?php  namespace App\Http\Controllers;  use Illuminate\Http\Request;use App\Models\Post;use App\Models\Comment;  class PostController extends Controller{    /**     * Write code on Method     *     * @return response()     */    public function index(Request $request)    {        $post = Post::find(1);           $comment = new Comment;        $comment->comment = "Hi ItSolutionStuff.com";                   $post = $post->comments()->save($comment);    }}
```

```
<?php  namespace App\Http\Controllers;   use Illuminate\Http\Request;use App\Models\Post;use App\Models\Comment;  class PostController extends Controller{    /**     * Write code on Method     *     * @return response()     */    public function index(Request $request)    {        $post = Post::find(1);           $comment1 = new Comment;        $comment1->comment = "Hi ItSolutionStuff.com Comment 1";                   $comment2 = new Comment;        $comment2->comment = "Hi ItSolutionStuff.com Comment 2";                   $post = $post->comments()->saveMany([$comment1, $comment2]);    }}
```

Read Also: [Laravel 9 One to One Relationship Example](https://www.itsolutionstuff.com/post/laravel-9-one-to-one-relationship-exampleexample.html)

```
<?php   namespace App\Http\Controllers;  use Illuminate\Http\Request;use App\Models\Post;use App\Models\Comment;  class PostController extends Controller{    /**     * Write code on Method     *     * @return response()     */    public function index(Request $request)    {        $comment = Comment::find(1);        $post = Post::find(2);                   $comment->post()->associate($post)->save();    }}
```

I hope you understand of one to many relationship...

## [Eloquent: relationships in laravel-Phần 3](https://viblo.asia/p/eloquent-relationships-in-laravel-phan-3-MJykjmxyePB)

## Eloquent: relationships in laravel-Phần 3

Bài đăng này đã không được cập nhật trong 6 năm

Phần 1: [https://viblo.asia/trung.nn.92/posts/PdbGnoEdeyA](https://viblo.asia/trung.nn.92/posts/PdbGnoEdeyA)

Phần 2: [https://viblo.asia/trung.nn.92/posts/aRBvXWEokWE](https://viblo.asia/trung.nn.92/posts/aRBvXWEokWE)

\


_**Querying Relations**_

Vì tất cả các mối quan hệ của Eloquent được định nghĩa qua các function, bạn có thể gọi những function để có được một thể hiện của mối quan hệ mà không thực sự thực hiện các truy vấn về quan hệ. Ngoài ra, tất cả các loại của các mối quan hệ Eloquent cũng phục vụ truy vấn, cho phép bạn tiếp tục hạn chế chuỗi vào truy vấn relationship cuối cùng trước khi SQL thi hành trong cơ sở dữ liệu của bạn.

Ví dụ, hãy tưởng tượng một hệ thống blog, trong đó mỗi `User` model có nhiều `Post` model liên quan.

```
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get all of the posts for the user.
     */
    public function posts()
    {
        return $this->hasMany('App\Post');
    }
}
```

Bạn có thể truy vấn các `posts` trong mối quan hệ và thêm các giằng buộc cho relationship như sau:

```
$user = App\User::find(1);

$user->posts()->where('active', 1)->get();
```

Bạn có thể sử dụng bất kỳ query builder methods nào trong relationship.

\


**Relationship Methods Vs. Dynamic Properties**

Nếu bạn không cần phải thêm vào các giằng buộc cho 1 truy vấn Eloquent relationship, bạn có thể truy cập vào 1 relationship như là 1 property. Ví dụ, tiếp tục sử dụng `User` và `Post` model, chúng ta có thể truy cập đến tất cả các posts của user như sau:

```
$user = App\User::find(1);

foreach ($user->posts as $post) {
    //
}
```

Dynamic properties là "lazy loading", có nghĩa là nó sẽ chỉ tải dữ liệu của relationship khi bạn thực sự truy cập chúng. Bởi vì điều này, các developers thường sử dụng `eager loading` để truy cập vào các relationship. `Eager loading` cung cấp một sự giảm đáng kể trong các truy vấn SQL mà cần để thực hiện tải các relationship của model.

**Querying Relationship Existence**

Khi truy cập vào các record của 1 model, bạn muốn giới hạn kết quả của bạn dựa trên sự tồn tại của các relationship. Ví dụ, hãy tưởng tượng bạn muốn lấy tất cả các bài viết blog mà có ít nhất 1 comment. Để làm như vậy, bạn có thể vượt qua tên của các relationship với `has` method:

```
// Retrieve all posts that have at least one comment...
$posts = App\Post::has('comments')->get();
```

Bạn cũng có thể chỉ định 1 operator và đếm để tùy chỉnh cho truy vấn:

```
// Retrieve all posts that have three or more comments...
$posts = Post::has('comments', '>=', 3)->get();
```

Các câu lệnh lồng nhau cũng có thể được xây dựng bằng các dấu ".", Ví dụ, bạn có thể lấy hết các posts mà có ít nhất 1 comment và vote:

```
// Retrieve all posts that have at least one comment with votes...
$posts = Post::has('comments.votes')->get();
```

Nếu bạn cần nhiều hơn nữa, bạn có thể sử dụng các method `whereHas` và `orWhereHas` đặt "where" trong điều kiện query của bạn. Những method này cho phép bạn thêm các ràng buộc tùy chỉnh cho 1 relationship, chẳng hạn như kiểm tra nội dung của 1 comment:

```
// Retrieve all posts with at least one comment containing words like foo%
$posts = Post::whereHas('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
})->get();
```

**Querying Relationship Absence**

Khi truy cập vào các record của 1 model, bạn muốn giới hạn kết quả dựa trên sự vắng mặt của 1 relationship. Ví dụ, hãy tưởng tượng bạn muốn lấy tất cả các posts mà không có bất kỳ comment nào, Để làm như vậy, bạn có thể sử dụng method `doesntHave`.

```
$posts = App\Post::doesntHave('comments')->get();
```

Nếu bạn cần nhiều hơn nữa, bạn có thể sử dụng method `whereDoesntHave` đặt "where" trong điều kiện query của bạn. Method này cho phép bạn thêm các ràng buộc tùy chỉnh cho 1 relationship, chẳng hạn như kiểu tra nội dung của 1 comment:

```
$posts = Post::whereDoesntHave('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
})->get();
```

**Counting Related Models**

Nếu bạn muốn đếm số lượng các kết quả từ 1 relationship mà không load chúng, bạn có thể sử dụng `withCount` method, bạn sẽ đặt cột `{relation}_count` trên result model của bạn. Ví dụ:

```
$posts = App\Post::withCount('comments')->get();

foreach ($posts as $post) {
    echo $post->comments_count;
}
```

Bạn có thể thêm "counts" cho nhiều relations cũng như thêm ràng buộc cho các truy vấn:

```
$posts = Post::withCount(['votes', 'comments' => function ($query) {
    $query->where('content', 'like', 'foo%');
}])->get();

echo $posts[0]->votes_count;
echo $posts[0]->comments_count;
```

\


**Eager Loading**

Khi truy cập vào Eloquent relationship như property, các dữ liệu relationship là "lazy loaded". Điều này có nghĩa là các dữ liệu relationship không thực sự được load cho đến khi bạn truy cập vào property. Tuy nhiên, Eloquent có thể "eager load" các relationship vào thời điểm bạn truy vấn vào parent model. Eager loading làm giảm bớt các vấn đề truy vấn N+1. Để minh họa vấn đề truy vấn N+1, ta có `Book` model có liên quan đến `Author` model:

```
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * Get the author that wrote the book.
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}
```

Bây giờ, chúng ta hãy lấý tất cả các books và author của nó:

```
$books = App\Book::all();

foreach ($books as $book) {
    echo $book->author->name;
}
```

Vòng lặp này sẽ thực hiện 1 truy vấn để lấy ra tất cả các books trên bàn, sau đó 1 truy vấn cho từng book để lấy ra author. Vì vậy, nếu chúng ta có 25 books, vòng lặp này sẽ chạy 26 truy vấn: 1 truy vấn để lấy ra các books và 25 truy vấn để lấy ra author cho các books.

Rất may, chúng ta có thể sử dụng eager loading để giảm thiểu số truy vấn này chỉ còn 2 truy vấn. Khi truy vấn, bạn có thể chỉ định các relationship được load bằng `with` method:

```
$books = App\Book::with('author')->get();

foreach ($books as $book) {
    echo $book->author->name;
}
```

Với cách này, chỉ có 2 câu truy vấn được thực thi:

```
select * from books

select * from authors where id in (1, 2, 3, 4, 5, ...)
```

\


_Eager Loading Multiple Relationships_

Đôi khi bạn có thể cần phải eager load nhiều mối quan hệ khác nhau, Để làm như vậy, chỉ cần thêm argument cho `with` method:

```
$books = App\Book::with('author', 'publisher')->get();
```

\


_Nested Eager Loading_

Để eager load các mối quan hệ lồng nhau, bạn có thể sử dụng dấu ".". Ví dụ, hãy eager load tất cả các author của các books và tất cả các contact của author trong 1 Eloquent statement:

```
$books = App\Book::with('author.contacts')->get();
```

\


**Constraining Eager Loads**

Đôi khi bạn có thể muốn eager load 1 relationship, nhưng cũng thêm 1 số ràng buộc cho câu truy vấn eager loading. Dưới đây là 1 ví dụ:

```
$users = App\User::with(['posts' => function ($query) {
    $query->where('title', 'like', '%first%');
}])->get();
```

Trong ví dụ này, Eloquent sẽ chỉ eager load các posts với điều kiện cột title của nó có chứa chữ "first". Dĩ nhiên, bạn có thể gọi các query builder method khác cho tùy chỉnh của bạn.

```
$users = App\User::with(['posts' => function ($query) {
    $query->orderBy('created_at', 'desc');
}])->get();
```

\


**Lazy Eager Loading**

Đôi khi bạn có thể cần phải eager load 1 relationship theo parent model đã được lấy ra. Ví dụ, điều này có thể hữu ích nếu bạn cần phải tự động quyết định để load các model liên quan:

```
$books = App\Book::all();

if ($someCondition) {
    $books->load('author', 'publisher');
}
```

Nếu bạn cần phải thiết lập các truy vấn rằng buộc vào các truy vấn eager loading, bạn có thể vượt qua một mảng mới quan hệ bạn muốn load. Các giá trị mảng nên là thể hiện của `Closure`:

```
$books->load(['author' => function ($query) {
    $query->orderBy('published_date', 'asc');
}]);
```

\


_**Inserting & Updating Related Models**_

\


**The Save Method**

Eloquent cung cấp phương thức thuận tiện cho việc thêm các models tới 1 relationships. Ví dụ, có lẽ bạn cần phải chèn thêm 1 `Comment` cho 1 `Post` model. Thay vì tự thiết lập attribute `post_id` vào `Comment`, bạn có thể chèn `Comment` trực tiếp từ method `save` của relationships:

```
$comment = new App\Comment(['message' => 'A new comment.']);

$post = App\Post::find(1);

$post->comments()->save($comment);
```

Chú ý rằng chúng ta đã không truy cập `comments` relationships như một thuộc tính động (dynamic property). Thay vào đó, chúng ta gọi `comments` method để có được một thể hiện của relationships. Phương thức `save` sẽ tự động thêm giá trị post\_id phù hợp với `Comment` model.

Nếu bạn cần `save` nhiều models có liên quan, bạn có thể sử dụng `saveMany` method:

```
$post = App\Post::find(1);

$post->comments()->saveMany([
    new App\Comment(['message' => 'A new comment.']),
    new App\Comment(['message' => 'Another comment.']),
]);
```

**The Create Method**

Ngoài `save` và `saveMany` methods, bạn có thể sử dụng `create` method, mà chấp nhận 1 mảng các thuộc tính, tạo ra 1 model và chèn nó vào cơ sở dữ liệu. Một lần nữa, sự khác biệt giữa `save` và `create` là `save` chấp nhận một thể hiện của Eloquent model đầy đủ trong khi `create` chấp nhận 1 mảng PHP:

```
$post = App\Post::find(1);

$comment = $post->comments()->create([
    'message' => 'A new comment.',
]);
```

**Belongs To Relationships**

Khi cập nhật 1 `belongsTo` relationship, bạn có thể sử dụng `associate` method. Method này sẽ set foreign key trên model con.

```
$account = App\Account::find(10);

$user->account()->associate($account);

$user->save();
```

Khi loại bỏ `belongsTo` relationship, bạn có thể sử dụng `dissociate` method. Method này sẽ thiết lập các foreign key thành `null`.

```
$user->account()->dissociate();

$user->save();
```

**Many To Many Relationships**

Eloquent cũng cung cấp cấp thêm một vài helper method để làm việc với các model liên quan 1 cách thuận tiện. Ví dụ, hãy tưởng tượng 1 user có thể có nhiều roles và 1 role có thể có nhiều users. Để gắn 1 role cho 1 user bằng cách chèn 1 bản ghi trong bảng trung gian, sử dụng `attach` method:

```
$user = App\User::find(1);

$user->roles()->attach($roleId);
```

Khi gắn 1 relationship với 1 model , bạn cũng có thể thêm vào 1 mảng dữ liệu bổ sung sẽ được chèn vào bảng trung gian:

```
$user->roles()->attach($roleId, ['expires' => $expires]);
```

Dĩ nhiên, đôi khi nó có thể là cần thiết để loại bỏ 1 role từ 1 user. Để loại bỏ 1 quan hệ many-to-many record, sử dụng `detach` method. Phương thức `detach` sẽ loại bỏ các bản ghi phù hợp ra khỏi bảng trung gian. Tuy nhiên, cả 2 model vẫn còn lại trong cơ sở dữ liệu.

```
// Detach a single role from the user...
$user->roles()->detach($roleId);

// Detach all roles from the user...
$user->roles()->detach();
```

Để thuận tiện, `attach` và `detach` cũng chấp nhận đầu vào là mảng:

```
$user = App\User::find(1);

$user->roles()->detach([1, 2, 3]);

$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
```

**Syncing Associations**

Bạn cũng có thể sử dụng `sync` method để xây dựng many-to-many associations. Phương thức `sync` chấp nhận 1 mảng các ID để đặt trên các bảng trung gian. Bất kỳ ID mà không phải là trong mảng sẽ được đưa ra khỏi bảng trung gian. Vì vậy, sau khi hoạt động này hoàn tất, chỉ có các ID có trong mảng sẽ tồn tại trong bảng trung gian.

```
$user->roles()->sync([1, 2, 3]);
```

Bạn cũng có thể thêm giá trị bảng trung gian với các ID:

```
$user->roles()->sync([1 => ['expires' => true], 2, 3]);
```

Nếu bạn không muốn detach ID đang tồn tại, bạn có thể sử dụng `syncWithoutDetaching` method.

```
$user->roles()->syncWithoutDetaching([1, 2, 3]);
```

**Saving Additional Data On A Pivot Table**

Khi làm việc với 1 mối quan hệ many-to-many, `save` method chấp nhận 1 mảng của bảng trung gian thêm thuộc tính như là đối số thứ 2 của nó.

```
App\User::find(1)->roles()->save($role, ['expires' => $expires]);
```

**Updating A Record On A Pivot Table**

Nếu bạn cần update 1 hàng hiện có trong pivot table của bạn, bạn có thể sử dụng phương thức `updateExistingPivot`. Phương thức này chấp nhận các pivot record foreign key và 1 mảng các thuộc tính để update:

```
$user = App\User::find(1);

$user->roles()->updateExistingPivot($roleId, $attributes);
```

\


Như vậy là chúng ta đã tìm hiểu xong về Relationship trong Eloquent rồi. Hy vọng bài viết này sẽ giúp ích được cho các bạn! ^^
