9
votes

Laravel seems like a very nice PHP framework, bundled with a good ORM (Eloquent). However, the laravel docs are some what lacking. Only the basic stuff is present in the doc.

Anyway, I have a problem when it comes to Eloquent and model relationships when it spans more than 2 models.

For example, I have the following scenario.

I have four database tables namely: users, locations, users_locations, packages. And the relationship between the model/tables are as follows:

User can belong to many Location and vice-versa. A location can have many packages.

And my corresponding model relationships are as follows:

//User Model:
public function locations(){
    return $this->belongsToMany('Location', 'users_locations', 'user_id', 'location_id');
}

//Location Model:
public function users(){
    return $this->belongsToMany('User', 'users_locations', 'location_id', 'user_id');
}
public function packages(){
    return $this->hasMany('Package', 'location_id');
}

//Package Model:
public function location(){
    return $this->belongsTo('Location', 'location_id');
}

What do I want to do?: I want to get all the packages belong to a user. A user belongs to locations, and packages also belong to locations. So from all the locations that belong to the user, I want to retrieve the packages those belong to those locations of the user. I also want the result set to be paginated.

I have tried the following:

//get the logged in user ID
$userId = Auth::user()->id
//first get all the locations of the user
$locations= User::with('locations')->find($userId)->locations;
//declare an empty array to store the packages
$packages = array();
//now loop through the locations
foreach($locations as $location){
    //since each location can have many packages, we also have to loop through the packages
    foreach($location->packages as $package){
        //store the plan in the array
        $packages[] = $package;
    }
}
//ok now we got the list of packages
return $packages;

The problem is, with the above, I cannot implement pagination on the packages. Does anyone know how to do it properly and in an efficient manner using Eloquent? Or is it just not possible?

1

1 Answers

8
votes
//get the logged in user ID
$userId = Auth::user()->id
//first get all the locations of the user
$locations= User::with('locations')->find($userId)->locations;


/* perhaps you can alternatively use lists() function to get the ids
 something like: $loc_ids = DB::table('locations')->where('user_id',$userId)->lists('id'); */
$loc_ids = array();
foreach($locations as $location)
{
   $loc_ids[] = $location->id;
}

$packages = Package::whereIn('location_id', $loc_ids)->skip($offset)->take($page_size)->get();

return $packages;