laravel collection of collections count

- 1 answer

Ad

I am trying to get a record count from a nested relationship. I would like to get the total number of sheep that belong to the field and the same for the farm but have no idea how to accomplish this without iterating through the @foreach loops and updating a variable. Eloquent is very clean so I feel like there is a simple elegant solution.

Thanks

I have 4 models, farm, field, shepherd, sheep which are hasMay relationships

class Farm extends Model {

    protected $fillable = ['name, user_id'];

    public function fields() {
        return $this->hasMany('App\Field');
    }   

    public function fieldCount() {
        return $this->fields->count();
    }

}

class Field extends Model {

    protected $fillable = ['name, farm_id, user_id'];

    public function farm() {
        return $this->belongsTo('App\farm');
    }

    public function shepherds() {
        return $this->hasMany('App\Shepherd');
    }

    public function group() {
        return $this->belongsTo('App\Group');
    }

    public function shepherdCount() {
        return $this->shepherds->count();
    }

    public function shepherdSheepCount() {
        return $this->
    }

}


class Shepherd extends Model {

    protected $fillable = ['name, field_id, user_id'];

    public function field() {
        return $this->belongsTo('App\Field');
    }

    public function sheep() {
        return $this->hasMany('App\Sheep');
    }   

    public function sheepCount() {
        return $this->sheep->count();
    }

}

class Sheep extends Model {

    protected $fillable = ['name, shepherd_id, user_id'];

    public function shepherd() {
        return $this->belongsTo('App\Shepherd');
    }

    public function meals() {
        return $this->hasMany('App\Meal');
    }

}


#CONTROLLER METHOD
public function test()
{
    $Farms = Farm::with('fields',
                        'fields.shepherds',
                        'fields.shepherds.sheep')->get();
    return view('test')->with('farms', $Farms);
}



#VIEW
                    <ul>
                        @foreach ($farms as $farm)
                            <li>{{$farm->name}} Farm - {{$farm->fieldCount()}}</li>

                            <ul >
                            @foreach ($farm->fields as $field)
                                <li>{{$field->name}} Field - {{ $field->shepherdCount()}}</li>
                                    <ul>
                                        @foreach ($field->shepherds as $shepherd)
                                            <li>
                                            Shepherd  {{ $shepherd->name }} has 
                                            {{ $shepherd->sheepCount() }} sheep
                                            </li>   
                                        @endforeach
                                    </ul>     
                            @endforeach
                            </ul>   
                        @endforeach  
                    </ul>

RESULT OF VIEW

Idaho Farm - 2
    West Mervinland Field - 3
        Shepherd Fermin has 61 sheep
        Shepherd Clement has 54 sheep
        Shepherd Ned has 57 sheep
    North Mariellebury Field - 2
        Shepherd Chadrick has 53 sheep
        Shepherd Jackson has 61 sheep
Washington Farm - 0
California Farm - 4
    Andersonport Field - 0
    South Carmenborough Field - 3
        Shepherd Alfonzo has 49 sheep
        Shepherd Boris has 59 sheep
        Shepherd Omari has 53 sheep
    West Archibaldhaven Field - 4
        Shepherd Darrin has 64 sheep
        Shepherd Davion has 53 sheep
        Shepherd Miller has 51 sheep
        Shepherd Kristoffer has 59 sheep
    Cassinmouth Field - 2
        Shepherd Paxton has 50 sheep
        Shepherd Hayley has 56 sheep
Ad

Answer

Ad

This is how it should be

class Sheep extends Model {

    //specify the table explicitly otherwise laravel will assume sheeps
    protected $table = 'sheep';

    //sheep belongs to a field
    public function field(){
        return $this->belongsTo('App\Field', 'foreign_key', 'primary_key');
    }

}

class Field extends Model {


    //field belongs to a farm
    public function farm() {
        return $this->belongsTo('App\Farm', 'foreign_key', 'primary_key');
    }

    //field has many sheep
    public function sheep() {
        return $this->hasMany('App\Sheep', 'foreign_key', 'primary_key');
    }

}

class Farm extends Model {

    //farm has many fields
    public function fields() {
        return $this->hasMany('App\Field');
    }

}

get results like this

$farm->fields // would always return collection since 1-many relation so you //have to loop through it 
    foreach($fields as $field){
        $field->sheep;//this will also return collection
}

you can apply all collections method on these, probably count() is a method too, see laravel collections' doc for more info.

Ad
source: stackoverflow.com
Ad