Binding to binding to binding to Laravel

I am developing an API using Laravel for use with a mobile application, and I am having some problems with binding a route model on nested routes. The application will have standalone sqlite db, which will synchronize client travel with the central server when the network is available. For this reason, the PC in the application cannot be used to access records on a central server. Each user will have a unique username that will be stored on a central server in a table with the following columns:

  • user_id
  • Username

The following columns will be presented in the routing table:

  • journey_id
  • user_id
  • user_journey_id

where user_journey_id will be the PK of the trip record on the client device. The idea is that clients can access the api with something like: http://example.com/api/client/UNIQUE_USERNAME/journey/1234 to get a trip from a central server.

I have the following resource setting:

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

and successfully configured the routing model binding for the client as follows:

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

I'm having trouble setting up the model’s nested binding, because I need a username client in combination with user_journey_id to get the correct path. Is there any way to do this with reference to the route model?
Or it should be done only in the controller, for example:

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

This is how I do it at the moment, but linking the route model will certainly make it a little easier.

+8
php laravel
source share
2 answers

Linking multiple URL parameters to models is certainly possible in Laravel, just like linking a nested route model.

One caveat is that you will need to specify routes individually for these specific routes, rather than using the Laravel resource controllers, as you used in your example.

To register a route with more than one model binding, you need to do something like this:

Route Definition:

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

Binding Definitions:

 $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(); }); 

Then you will find that both models solve and introduce the action method in the controller class:

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

The only real drawback to this approach is the fact that you need to define routes manually instead of using the convenient Laravel resource controllers. Of course, you could implement some of your own logical solutions to simplify these types of routes.

+2
source share

I think your approach is not very good, and you will end up using a separate controller for this anyway, since you will probably need to add an auth level or more functionality in the future.

Having a username in a URL is not good, because it can be a string with special characters that will be encoded in the URL, then decoded, and therefore error prone. I would suggest using identifiers as an API.

Resources will call a specific method for each action requested, I would recommend using these methods.

0
source share

All Articles