djb
djb

Reputation: 6021

How do implement many-to-many relationships in a Laravel 4 RESTful API

I'd like to implement something similar to what's asked in this question in Laravel 4, where a player/ resource can have more than one team/, and vice-versa.

In an ideal world I would be able to query

players/1/teams

and get back some JSON like this:

{ player: { 
    id: 1, name: 'Bob', sport: 'Curling', teams: [
        { id: 1, name: 'Northern Curling Soc.', age: 2}, 
        { id:2, name: 'Southern Curling Soc.', age: 4 }
    ] 
}

or

teams/{id}/players and get the correlative.

Obviously if I were using Laravel's views I could simply call $player->teams and all would be well, but this is for a JSON API so it all needs to be up front.

I also need to be able to paginate the related results, although this is probably a different question.

How can I do this with Laravel?

Thanks for any help!

Upvotes: 4

Views: 1774

Answers (2)

idmadj
idmadj

Reputation: 2645

Laravel 4 added support for nested resources routes. They're pretty nice, and seem perfectly suited for this.

Basically, in addition to your "direct" resource controllers, you need to add routes for your nested resources. In this case, in addition to :

Route::resource('players', 'PlayersController');  // players/#
Route::resource('teams', 'TeamsController');      // teams/#

... you'd need:

Route::resource('players.teams', 'PlayerTeamsController');  // players/#/teams/#
Route::resource('teams.players', 'TeamPlayersController');  // teams/#/player/#

Then in your controllers, methods that usually receives a single ID as parameter will now receive two (the order is defined by your route):

class PlayerTeamsController extends Controller {

    public function show($player_id, $team_id) {

    }

}

You can then use inheritance to avoid code redundancy between your controllers.

Upvotes: 5

Oddman
Oddman

Reputation: 3959

Via the API, just include the relationship and return the object (in laravel 4). L4 will automatically format the data for JSON output.

return Player::with( [ 'teams' ] )->get();

It will give you pretty much exactly the format you're after :)

Upvotes: 1

Related Questions