If you want to retrieve count
for multiple modules using eager loading then you need such a 'helper' relation setup:
// Module model
public function sectionsCountRelation()
{
return $this->hasOne('Section')->selectRaw('module_id, count(*) as count')->groupBy('module_id');
// replace module_id with appropriate foreign key if needed
}
// then you can access it like this:
$modules = Module::with('sectionsCountRelation')->get();
$modules->first()->sectionsCountRelation->count;
// but there is a bit sugar to make it easier (and that s why I renamed it to sectionsCountRelation)
public function getSectionsCountAttribute()
{
return $this->sectionsCountRelation->count;
}
// now you can simply do this on every module:
$modules->first()->sectionsCount;
Wow! I don't understand one iota of this code, but.... it works (after changing your typo Posts to Sections)!
I have a lot, a lot, a lot to learn.
Thanks!
Yes, I copy-pasted the code from my Category - Post relations :) Typo fixed.
The idea behind this one is that you call accessor
inside of which you call relation. If the relation is already loaded, then you fetch its property, if not it will be loaded first, because this is how dynamic properties
work.
You could also wonder why this is hasOne relation, right?
It's becuase hasMany
returns a Collection, while hasOne
returns a single object.
So if we used hasMany on this we would need to call the count like this:
$module->sectionsCountRelation->first()->count;
which is not very convenient.
hasOne is also the choice here, as in fact there is ONE related row in the end (aggregate count).
Thanks for the tip, worked great for me, one thing to mention, if the relation has no records you get a Trying to get property of non-object
Fixed by adding a check for NULL within the accessor
public function getSectionsCountAttribute()
{
return $this->sectionsCountRelation?$this->sectionsCountRelation->count:0;
}
Just to add to the solution provided by @jarektkaczyk in case you have morphMany relationship to model then use it in this way Taking use case of Post -> Image model
public function images()
{
return $this->morphMany('Image', 'imageable');
}
public function imagesCountRelation()
{
return $this->images()->selectRaw('imageable_id, count(*) as count')->groupBy('imageable_id');
}
and
public function getImagesCountAttribute(){
return $this->imagesCountRelation->first() ? $this->imagesCountRelation->first()->count : 0;
}
Just in case anybody comes across this - there is a better, built-in way now:
https://laravel.com/docs/5.4/eloquent-relationships#counting-related-models
Hi, I didnt understand where excactly you put that code? in the model or the controller. I have tags in my posts and in tags page I want to get the count of how many posts are there with that tag so the relation in tags is like
public function articles(){ return $this->belongsToMany('App\Article'); }
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community