Reputation: 5880
I have been trying to filter students belonging to a sub-class based on a filter criteria (say the last name of the student).
In my Laravel 5.0 app, I have models Subclass
and Student
where their relationship and class definition are as follows:
Relationship:
Subclass
HasMany Student
(s)
Model definitions:
class Subclass extends Eloquent {
.
.
.
public function students() {
return $this->hasMany('App\Models\Student');
}
}
class Student extends Eloquent {
.
.
.
public function subclass() {
return $this->belongsTo('App\Models\Subclass');
}
public function scopeFilterStudents($query, $filter){
return $query->where('last_name', 'like', '%'. $filter .'%');
}
}
The Issue:
The problem arises when I try to filter the students in a particular subclass using whereHas
as such:
$students = Subclass::whereId(1)->whereHas('students', function($query){
return $query->filterStudents(Input::get('filter'));
})->get();
I've followed the documentation on filtering queried models and technically, it should be working, but it isn't filtering as expected (in fact, it isnt filtering at all and I don't get a students
key if I cast the result into an array).
Workaround:
On the other hand, if I eager load (below) the fetched models (i.e. with with
method), the models are filtered with the same filter criteria (AND, I do get a students
key if the returned collection is cast into an array).
$students = Subclass::whereId(1)->with(['students' => function($query){
return $query->filterStudents(Input::get('filter'));
}])->get();
id
specified here using whereId
is optional, as omitting it would take all sub-classes into account.So, is there any problem with my implementation of the whereHas
method, or else, does the whereHas
itself have any issue(s) filtering models.
Any help in this regards would be appreciated.
Upvotes: 2
Views: 1924
Reputation: 6544
The problem is that you're fetching objects of the wrong model. What you're doing in your first approach is fetching all SubClasses
that have an ID of 1 and at least one Student
record to which the given filter applies. So if you want to get Students
of this SubClass
, you can simply invert the query:
$students = Student::whereHas('subClass', function($q) use ($subClassId) {
return $q->whereId($subClassId);
})->filterStudents(Input::get('filter'))->get();
Your second approach is valid as well, but you're fetching a SubClass
with its Students
, so if I got your explanation right, you get more than you actually want or need.
It is also possible that I missunderstood your question and you're trying to get all Students
that have at least one relation to a SubClass
. If so, you can use this query:
$students = Student::has('subClass')->get();
Upvotes: 2