This is Part 2 of our Laravel 8 Eloquent Relationships Tutorial
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('AppModelsComment');
}
in Models/Comment.php
protected $fillable = [
'student_id',
'comment',
];
public function student()
{
// return $this >belongsTo('Model', 'foreign_key', 'owner_key');
return $this >belongsTo('AppModelsStudent','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:
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:
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:
Fetching Students who doesn't have comments:
public function index(){
$student = Student::doesntHave('comment') >get();
dd($student);
}
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:
Accessing the comments only:
foreach ($student as $comment){
dd($comment >comment);
}
Result:
Accessing only specific columns in a comment
Change the comment Models/Student to
public function comment()
{
return $this >hasMany('AppModelsComment','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);
}
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);
Get count of comments for each student
$student = Student::withCount('comment') >get();
dd($student);
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:
Awesome we've completed lots of exercises!
Click this link to proceed with the next tutorial Many to Many Relationship!