I have a classroom model with a hasMany students relationship. I want to check if every classroom has students in one query with eloquent builder. I dont want to retireve the student count either. The has function filters the classrooms that doesn’t have students:
//Classroom model
class Classroom extends Model
{
public function students(): HasMany
{
return $this->hasMany(Student::class);
}
}
Tried with:
Classroom::has('students')->get();
But it only returns the models with students, not what I want. Expected result:
[
{
"has_students": false
},
{
"has_students": false
},
{
"has_students": true
},
{
"has_students": true
},
{
"has_students": false
}
]
4
Answers
You can do it with:
That is, use Eqloquent to join classrooms table with the count of students in each classroom, and then map the results with your condition.
Try adding has_stuents attribute accessor
As a follow up to Amade’s answer, we now have a
withExists
method for just checking existence of relationships. So you should be able to do something like this:Then, each
Classroom
object will have a property (attribute) namedstudents_exists
(I believe based on the documentation). You could alias this tohas_students
if you would like:I have not tested this, but based on the documentation this should be what you are looking for.
If you want that specific structure of data returned you can do what Amade demonstrated with the
mapWithKeys
method or use a transformer (API Resource).Laravel 10.x Docs – Eloquent – Relationships – Other Aggregates –
withExists
You can add a "hasStudents" method to the Classroom model that uses the "exists" method to check if there are any students associated with the class. Here’s an example code to do that:
Then, to get the array of objects with the "has_students" property that indicates whether each class has students, you can run a query to retrieve all classrooms and use the "map" method to create the desired array:
Finally, you can convert $classroomData to JSON using the "toJson" method:
This will produce the desired JSON array with the "has_students" property for each class.