Support the ongoing development of Laravel.io →
posted 10 years ago
Eloquent
Last updated 2 years ago.
0

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;
Last updated 2 years ago.
0

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!

Last updated 2 years ago.
0

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).

Last updated 2 years ago.
0

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;
}
Last updated 2 years ago.
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;
}
Last updated 2 years ago.
0

A nice solution to the problem was posted here.

0

@FractalizeR: Thanks for the link!

Last updated 9 years ago.
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

Last updated 7 years ago.
0

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'); }

Last updated 6 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

macliems macliems Joined 8 Apr 2014

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.