Laravel 8- Eloquent Relationships Tutorial - One to Many Relationship
Tags: php, laravel, erd, beginners
Published: 2022-02-06 07:42:27

This is Part 2 of our Laravel 8 - Eloquent Relationships Tutorial


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5639xr6kdnr9m5nlptx0.PNG)

Let's start by creating the database table
`php artisan make:migration create_comments_table`

go to app/database/migrations:

```
Schema::create('comments', function (Blueprint $table) {
            $table->id();
            $table->foreignId('student_id');
            $table->string('comment');
            $table->timestamps();
        });
```

copy and save

run migration to create tables
`php artisan migrate`
check in your database if successful

Now let's create the model of comments
`php artisan make:model Comment`

> models should be singular while the table is plural

**One to Many Relationships**

Go to app/Models and open the student model and the comment models

define the one to many relationship
in Models/Student.php

```
public function comment()
    {
        return $this->hasMany('App\Models\Comment');
    }
```

in Models/Comment.php
```
protected $fillable = [
        'student_id',
        'comment',
    ];

    public function student()
    {
        // return $this->belongsTo('Model', 'foreign_key', 'owner_key'); 
        return $this->belongsTo('App\Models\Student','student_id','id');
    }
```
_this will define the relationship between the two models_

Create the Controllers and Routes

using the StudentController we made in part 1 lets create the function to create 3 comments under 1 student

go to app/Http/Controllers/StudentController

```
public function store_comment(){

        $student = Student::find(1);

        $comment = new Comment;
        $comment->student_id = $student->id;
        $comment->comment = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the indust';
        $comment->save();

        $comment = new Comment;
        $comment->student_id = $student->id;
        $comment->comment = 'king it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydne';
        $comment->save();

        $comment = new Comment;
        $comment->student_id = $student->id;
        $comment->comment = 'ed to be sure there isnt anything embarrassing hidden in the middle of text. All the Latin words,';
        $comment->save();

        dd($comment);
    }
```
> this is for example purposes of creating multiple comments only

create routes in app/routes/web.php

```
Route::get('/students/store/comment', [StudentController::class,'store_comment'])->name('storeComment');
```
in your browser go to http://localhost:8000/students/store/comment to create 3 entry in the database

it should look similar to:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ouuw7ciymdvhrx4j51lt.PNG)

Now change the index in StudentController to

```
public function index(){
        $student = Student::find(1);
        dd($student->comment);
    }
```
go to http://localhost:8000/students to check the models

it should look similar to:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wq0rdyzusd02l4c8ecsi.PNG)

> Hurray! We have successfully created our One to Many Relationship.

Now let's add queries when fetching our eloquent model

**Fetching Students who have atleast 1 comment:**
```
public function index(){
        $student = Student::has('comment')->get();
        dd($student);
    }
```
Result:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yd6e3wmkpa3pv5qfv85.PNG)

**Fetching Students who doesn't have comments:**

```
public function index(){
        $student = Student::doesntHave('comment')->get();
        dd($student);
    }
```
Result:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9skpwkwc5qqg08cfs6n.PNG)

**Fetching Students who have atleast 2 comments:**
```
public function index(){
        $student = Student::has('comment','>=',2)->get();
        dd($student);
    }
```
**Fetching a Student with all his/her comments in descending order:**
```
$student = Student::where('id',1)->with(['comment' => function($query) {
            $query->orderBy('id','desc');
        }])->get();
        dd($student);
```
Result:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/worm8drrvsb1gl4c52n4.PNG)

**Accessing the comments only:**
```
foreach ($student as $comment){ 
            dd($comment->comment);
        }
```
Result:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ug2i5hwceu9zvbjzgt9h.PNG)

**Accessing only specific columns in a comment**

Change the comment Models/Student to
```
public function comment()
    {
        return $this->hasMany('App\Models\Comment','student_id')->orderBy('id','desc');
    }
```
then the code to get only specific column on a relation

```
$student = Student::where('id',1)->with(['comment:id,student_id,comment'])->get();

        foreach ($student as $comment){ 
            dd($comment->comment);
        }
```
Result:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dwrxwgv03ivn10e9yfyn.PNG)
> Note: Primary Key id and Foreign Key student_id needs to be specificied for this to work

**Get a student with a specific condition in the comments table:**
```
$student = Student::whereHas('comment',function($query){
            $query->where('comment','like','%king%');
        })->get();
dd($student);
```
Result:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnqt4hwkr3ko3ppb91b8.PNG)

**Get count of comments for each student**
```
$student = Student::withCount('comment')->get();
dd($student);
```
Result:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5x9opo73henmwgs7rnqa.PNG)

**Get count of comments for each student order by comment_count desc**
```
$student = Student::withCount('comment')->orderBy('comment_count','desc')->get();
dd($student);
```
**Get count of comments for each student with a specific critera**
- get count of comments from students who have comments with the word king in it , result should only be 1

```
$student = Student::withCount(['comment' => function($query) {
            $query->where('comment','like','%king%');
        }])->get();
dd($student);
```
Result:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tjb2mk687n0jix3p2xty.PNG)

> Awesome we've completed lots of exercises!
> Click this [link](https://dev.to/dalelantowork/laravel-8-eloquent-relationships-tutorial-many-to-many-relationship-15a2) to proceed with the next tutorial - Many to Many Relationship!