Implicit Binding
Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name.
For example:
Create below route in web.php file
Route::get('api/users/{user_id}', function (App\User $user) {
return $user->email;// we get user email
});
After creating just pass url in google chrome (http://localhost/laraveldemoproject/public/api/users/1) you get user email id
Since the $user
variable is type-hinted as the App\User
Eloquent model and the variable name matches the {user}
URI segment, Laravel will automatically inject the model instance that has an ID matching the corresponding value from the request URI.
If a matching model instance is not found in the database, a 404 HTTP response will automatically be generated.
Customizing The Key
Sometimes you may wish to resolve Eloquent models using a column other than id
. To do so, you may specify the column in the route parameter definition:
Create new controller model and migration file using below command in command prompt
php artisan make:controller democontroller -mcr
Now create new route to access data as below
Route::get('api/demos/{demo:id}', function (App\demo $demo) {
return $demo;
});
Custom Keys & Scoping
Sometimes, when implicitly binding multiple Eloquent models in a single route definition, you may wish to scope the second Eloquent model such that it must be a child of the first Eloquent model.
For example, consider this situation that retrieves a blog demo by id for a specific user:
use App\demo;
use App\User;
Route::get('api/users/{user}/demos/{demo:id}', function (User $user, demo $demo) {
return $demo;
});
When using a custom keyed implicit binding as a nested route parameter, Laravel will automatically scope the query to retrieve the nested model by its parent using conventions to guess the relationship name on the parent. In this case, it will be assumed that the User
model has a relationship named demos(the plural of the route parameter name) which can be used to retrieve the demos model.
Customizing The Default Key Name
If you would like model binding to use a default database column other than id
when retrieving a given model class, you may override the getRouteKeyName
method on the Eloquent model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class demo extends Model
{
protected $fillable = [
'title', 'description'
];
public function getRouteKeyName()
{
return 'title';
}
}
Explicit Binding
Example(1)
Create service provider in provider folder using below commands
php artisan make:provider demoServiceProvider
model
method to specify the class for a given parameter.boot
method of the RouteServiceProvider
class:
Open demoServiceProvider.php and implement below code in that file
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\User;
class demoServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
parent::boot();
Route::model('user', User::class);
}
}
Next, define a route that contains a {user}
parameter:
Route::get('profile/{user}', function (App\User $user) {
return $user->name;
});
Pass url in google chrome as below url
http://localhost/laraveldemoproject/public/profile/1
Since we have bound all {user}
parameters to the App\User
model, a User
instance will be injected into the route. So, for example, a request to profile/1
will inject the User
instance from the database which has an ID of 1
.
If a matching model instance is not found in the database, a 404 HTTP response will be automatically generated.
Customizing The Resolution Logic
If you wish to use your own resolution logic, you may use the Route::bind
method. The Closure
you pass to the bind
method will receive the value of the URI segment and should return the instance of the class that should be injected into the route:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\User;
class demoServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
parent::boot();
Route::bind('user', function ($value) {
return User::where('name', $value)->firstOrFail();
});
}
}
resolveRouteBinding
method on your Eloquent model. This method will receive the value of the URI segment and should return the instance of the class that should be injected into the route:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function resolveRouteBinding($value, $field = null)
{
return $this->where('name', $value)->firstOrFail();
}
}