Support the ongoing development of Laravel.io →
Views Architecture
Last updated 2 years ago.
0
  1. move all the logic to calculate sums in your models (Continens and Cities);
  2. in controller retrieve continents (and counties using eager loading) and pass only continents to view;
  3. in view iterate through continents and generate list
Last updated 2 years ago.
0

I tried to calculate sums in my models but it seems Eloquent doesn't let me return an integer:

Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation 

Country model:

public function stats() {
  return $this->hasMany('Stats', 'country_id', 'country_id');
}
    
public function nbDocuments() {
  return  $this->stats->sum('nb_documents');
}

Then, how can I do step 3 without retrieving countries within the view itself? I can retrieve them in the controller, but I still have to sort them according to their continent to display this kind of page (sorry, didn't displayed well in my OP):

Africa (7)
 - Burundi (4)
 - Madagascar (3) 
Asia (19)
- India (12) 
- Taiwan (7)
Last updated 2 years ago.
0

I did something along the lines of :

class ContinentsController extends BaseController {

  public function index() {
    $continents = Continent::orderBy('name')->with('countries.stats')->get();
    $arr_continents = array();
    $arr_countries = array();
        
    foreach ($continents as $continent) {    
      $nbDocumentsForContinent = 0;
      foreach ($continent->countries as $country) {        
        $nbDocumentsForCountry = $country->stats->sum('nb_documents');
        if ($nbDocumentsForCountry > 0) {
          $arr_countries[] = ['id' => $country->country_id, 'name' => $country->name, 'nb' => $nbDocumentsForCountry];
          $nbDocumentsForContinent += $nbDocumentsForCountry;
        }
      }
        
      if ($nbDocumentsForContinent > 0) {
        $arr_continents[] = ['name' => $continent->name, 'nb' => $nbDocumentsForContinent, 'countries' => $arr_countries];            
      }
			
      unset($arr_countries);
    }
    return View::make('country', ['continents' => $arr_continents]);
  }
}

And in my view :

@foreach ($continents as $continent)
  {{ link_to('#', $continent['name'].' ('.$continent['nb'].')', $attributes = array('class' => 'tiroir button')) }}
  <div class="collapsible">
    <ul class="tri_col">
      @foreach ($continent['countries'] as $country)
        {{ link_to_route('sector', $country['name'].' ('.$country['nb'].')', $parameters = array('country_id' => $country['id']), $attributes = array('class' => 'tiroir button')) }}
      @endforeach
    </ul>
  </div>
@endforeach

But I still do not know how to calculate those sums and return them inside my models (as I understood the error message posted above, a model method can only return one or multiple instance of the 'model object'. How can I do what longilineo said (move all the logic to calculate sums in your models)?

Thanks

Last updated 2 years ago.
0

Are you trying to access to nbDocuments method as a property?

$country->nbDocuments instead of $country->nbDocuments()

Last updated 2 years ago.
0

That was it, thanks.

So, correct me if I'm wrong but the difference between a property and a method in a model is that a property always return a '$this->hasMany', '$this->hasOne', '$this->belongsTo', etc, (and will be called without () ) whereas a method can return whatever the hell it wants (and will be called with () )?

Last updated 2 years ago.
0

Usually a method can return whatever the hell it wants (and will be called with () ).

Methods returning an object of type Illuminate\Database\Eloquent\Relations\Relation can be called as property. For example User::find(1)->posts is just an abbreviation for User::find(1)->posts()->get(); both will return collection while User::find(1)->posts() will return a query builder instance.

Other particular methods are getter and setter for attributes: http://laravel.com/docs/eloquent#accessors-and-mutators

Usually properties of an eloquent object return an attribute. The attributes are fields in a database table record. You can append custom attribute and define getter and setter for them: take a look at the last example http://laravel.com/docs/eloquent

Last updated 2 years ago.
0

Thank you for your time and explanations!

Last updated 2 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

SynRJ synrj Joined 3 Sep 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.