2015-07-23 28 views
8

Ich entwickle eine API mit Laravel für die Verwendung mit einer mobilen App und habe einige Probleme mit Route Model Binding auf geschachtelten Routen. Die App wird über eine eigenständige sqlite db verfügen, die Client-Reisen mit dem zentralen Server synchronisiert, wenn das Netzwerk verfügbar ist. Aus diesem Grund können die PKs in der App nicht für den Zugriff auf die Datensätze auf dem zentralen Server verwendet werden. Jeder Benutzer hat einen eindeutigen Benutzernamen haben, die auf dem zentralen Server in einer Tabelle mit den folgenden Spalten gespeichert werden:Laravel geschachtelte Route Modellbindung

  • User_id
  • Benutzername

Die Reise Tisch wird dann die folgenden Spalten:

  • j ourney_id
  • User_id
  • user_journey_id

wo die user_journey_id wird die PK des Fahrtdatensatzes auf dem Client-Gerät sein. Die Idee ist, dass die Clients können dann auf die API mit etwa wie folgt zugreifen: http://example.com/api/client/UNIQUE_USERNAME/journey/1234 , um die Reise vom zentralen Server abrufen.

Ich habe folgende Ressourcen Setup:

Route::resource('client','ClientController'); 
Route::resource('client.journey','JourneyController'); 

und Setup-Route Modell erfolgreich verbindlich für den Kunden wie folgt:

$router->bind('client', function($value, $route) { 
    return \App\Client::where('username', '=', $value)->firstOrFail(); 
}); 

Ich bin mit der Einrichtung ein wenig Mühe mit der verschachtelte Modellbindung, da ich den Client username in Verbindung mit dem user_journey_id benötige, um die korrekte Reise abzurufen. Gibt es eine Möglichkeit, dies mit dem Routenmodell zu tun? aber die Strecke Modell verbindlich wäre es sicherlich macht ein bisschen leichter

public function show(Client $client, $user_journey_id) 
{ 
    ... // have logic here to get the journey. 

Dies ist, wie ich es zur Zeit:
Oder sollte dies nur mit einigen wie in der Steuerung erfolgen.

+0

Anstatt den Benutzernamen zu verwenden, können Sie nicht einfach die Benutzer-ID verwenden, damit Sie die Modellbindung nicht verschachteln müssen. – Billy

Antwort

0

Ich denke, Ihr Ansatz ist nicht gut und Sie enden sowieso mit einem separaten Controller, wie Sie wahrscheinlich eine Auth-Layer in der Zukunft oder eine weitere Funktionalität hinzufügen müssen.

Mit dem Benutzernamen ist die URL auch nicht gut, da es eine Zeichenfolge mit Sonderzeichen sein kann, die URL-codiert werden, dann decodiert, so anfällig für Fehler. Ich würde vorschlagen, die IDs zu verwenden, da es eine API ist.

Ressourcen rufen für jede angeforderte Aktion eine bestimmte Methode auf, ich empfehle die Verwendung dieser Methoden.

2

Das Binden mehrerer URL-Parameter an Modelle ist in Laravel ebenso möglich wie das Verschachteln von Routenmodellen.

Eine Einschränkung besteht darin, dass Sie die Routen für diese bestimmten Routen einzeln angeben müssen, anstatt Laravels Ressourcen-Controller zu verwenden, wie Sie in Ihrem Beispiel verwendet haben.

Um eine Route mit mehr als einem Modell registrieren Bindung Sie, so etwas zu tun:

Die Route Definition:

Route::get('/api/client/{user}/journey/{journey}', [ 
    'as' => 'client.journey', 
    'uses' => '[email protected]' 
]); 

Die Binde Definitionen:

$router->bind('user', function($value, $route) { 
    return \App\Client::where('username', '=', $value)->firstOrFail(); 
}); 

$router->bind('journey', function($value, $route) { 
    return \App\Journey::where('user_journey_id', '=', $value)->firstOrFail(); 
}); 

Sie werden dann feststellen, dass beide Modelle aufgelöst und der Aktionsmethode in der Controller-Klasse hinzugefügt werden:

public function show(User $user, Journey $journey) 
{ 
    //do whatever you need to do here... 

Der einzige wirkliche Nachteil dieses Ansatzes ist die Tatsache, dass Sie Routen manuell definieren müssen, anstatt Laravels handliche Ressourcen-Controller zu verwenden. Natürlich könnten Sie einige Ihrer eigenen logischen implementieren, um diese Arten von Routen einfacher zu definieren.