Laravel 5.4 relationships - php

I have 3 models and a pivot table:
SchoolYear - model
id
Course - model
id
schoolyear_id
course_student - pivot table
course_id
student_id
Student - model
id
Relationships are:
a SchoolYear hasMany Course
a Course belongsToMany Student trough course_student
a Student belongsToMany Course trough course_student
What is the fastest, more elegant way to find the students rolled in to a schoolyear and also to be able to sort it by Student properties?
$year = SchoolYear::firstOrCreate(['anul'=>Carbon::now()->year]);
$courses = $year->courses;
$students = collect([]);
foreach($courses as $course){
$course_students = $course->students;
foreach($course_students as $course_student){
$students->push($course_student);
}
}
dd($year, $students);

Eloquent provides a set of methods to query relationship existence. has() if there are not conditions, or whereHas() if there is a condition.
So, in your case, you want the students that have a related school year.
$year = SchoolYear::firstOrCreate(['anul'=>Carbon::now()->year]);
// assumes Student has a "courses" relationship,
// and Course has a "schoolYear" relationship
$students = Student::whereHas('courses.schoolYear', function ($query) use ($year) {
return $query->where('anul', $year->anul);
})
->get();
dd($year, $students);

Related

Get only 3 records using with from many to many relationship Laravel

I'm using laravel 7 and
I have 3 tables shown below. I want first three students data instead of all student. tables have many to many relationship.
groups
id
name
students
id
name
group_student_pivot
group_id
student_id
created_at
I have below relationship in models
Groups model
public function students()
{
return $this->belongsToMany(Student::class,'group_student_pivot')->withPivot(['status'])->withTimestamps();
}
Student model
public function groups()
{
return $this->belongsToMany(Group::class,'group_student_pivot')->withPivot(['status'])->withTimestamps();
}
$groups = Group::whereIn('id',$groupIds)->with('students')->get();
In above query I want first 3 students data instead of all students.
You can get 3 records like this:
$groups = Group::whereIn('id',$groupIds)->with('students', function($q){
$q->take(3);
})->get();
You can use with and whereHas method
$groups = Group::with('students')->whereHas('students', function($q){
$q->take(3);
})->whereIn('id',$groupIds)->get();

How to filter a many to many relationship by a column in pivot table

My application has the following entities:
Locations
Disciplines
Instructors
Disciplines and Instructors should be a many to many relationship, so in my Discipline model I have the following:
public function instructors() {
return $this->belongsToMany(
Instructor::class,
'location_discipline_instructors',
'discipline_id',
'instructor_id'
);
}
My pivot table contains the following fields:
location_id
discipline_id
instructor_id
I can use this relationship to fetch all disciplines with the associated instructors, but I need to filter these results by the location_id in the pivot table.
How should I approach this?
I tried using wherePivot() with location_id, but with that approach, I ended up with a list of all system disciplines with instructors for any discipline that had instructors associated. I continued to research and ended up with this solution:
Discipline::whereHas('instructors', function ($query) {
return $query->where('location_id', '=', $this->locationId);
})->with('instructors')->get();

return many to many relation result in laravel and return null if it doesn't exist

i have a relation between tables subjects and teachers (many to many)
subjects
id
title
teachers
id
name
subject_teacher
id
subject_id
teacher_id
semester_id
this is my code with foreach and it return null if it doesn't exist
$subjects = Subject:all();
foreach ($subjects as $subject){
$subject->staff = $subject->staffSubjects()->wherePivot('semester_id',$semester->id)->first();
}
is there a way to get the staff of each subject with eloquent in one line without a loop and if it doesn't exist return null ?
Has
has() is to filter the selecting model based on a relationship. So it acts very similarly to a normal WHERE condition. If you just use has('relation') that means you only want to get the models that have at least one related model in this relation.
Example:
User > hasMany > Post
$users = User::has('posts')->get()

How to get all books from another table when using many to many relationship Laravel / Eloquent / Query builder

Let me explain the scenario.
i have tables:
competitions
id title body
then
books
id name user_id
then i have a pivot table to store participants
so
participants
id competition_id user_id
Now i have set some relationships for these models.
Competition model
public function participants()
{
return $this->belongsToMany('App\User');
}
User model
public function participatedCompetitions()
{
return $this->belongsToMany('App\Competition');
}
Now i am fetching one single competition and in that same query i need to fetch a list of books of the participants of that competition.
So how can i achieve this.
Thanks.
Here is how you get all the books:
$userIds = $competition->participant()->get()->pluck('id');
// $userIds is your collection of User Ids that is participant in that compititions.
$books = Book::whereIn('user_id',$userIds)->get();

retrieve data from 3 tables How to retrieve data from the last table using the first one in Laravel

I have three table:
Teacher
id
name
family_name
ClassRoom
class_name
teacher_id
Student
name
family_name
Teacher have one to many relation with ClassRoom
Student have many to many relation with ClassRoom
how can i retrieve all Students of a Teacher using Eloquent methods without using foreach?
$teacher = Teacher::with('classrooms.students')->find($someId); //eager load
$studentsArray = $teacher->classrooms->pluck('students'); //array of students with duplicates
$students = (new Collection($studentsArray))->collapse()->unique(); //collection of unique students
in your teacher model create a new relation like below:
public function students()
{
return $this->hasManyThrough(Student::class, ClassRoom::class);
}
now you just query the student like below:
$teacher = Teacher::where('id', '1')->first();
$students = $teacher->students;

Categories