Laravel Tips and Tricks
Eloquent
Route Model Binding
Route Model Binding is a great way to simplify code, and hence find records explicitly by their id. If the record is not found the result will be a 404. For example:
class ControllerExamples extends Controller
{
// Instead of this:
public function show($id)
{
$model_example = ModelExample::find($id);
return view('view', compact('model_example'));
}
// Do this:
public function show(ModelExample $model_example)
{
return view('view', compact('model_example'));
}
}
There are two ways to override Route Model Binding.
The first is by explicitly overriding
the getRouteKeyName()
function in the model by the column name:
class ModelExample extends Model
{
// From id column to slug column:
public function getRouteKeyName()
{
return 'slug';
}
}
The second way to retrieve the Model is through the RouteServiceProvider
(app/Providers/RouteServiceProvider.php
).
This way you can specify catches if not found through one column.
So in theory you can retrieve a record by the ID or slug.
class RouteServiceProvider extends ServiceProvider
{
public function boot()
{
parent::boot();
Route::bind('modelexample', function ($value) {
return ModelExample::where('id', $value)
->orWhere('slug', $value)
->first();
});
}
}
Model Observers
Eloquent models fire several events, such as the following: retrieved
,
creating
, created
, updating
, updated
, saving
, saved
, deleting
,
deleted
, restoring
, restored
. By creating a Model Observer you can set
global executable code each time a model class fires at one of the events.
For example:
class ModelExampleObserver
{
/**
* Handle the recipe "creating" event.
*
* @param \App\Recipe $recipe
* @return void
*/
public function creating(ModelExample $model_example)
{
$model_example->user_id = auth()->id();
$model_example->slug = str_slug($model_example->title);
}
}
Blade
Loops
If by chance a foreach is used, and a partial is required for each iteration,
then Laravel's @blade
provides a special syntax for this. For example:
<div class="row justify-content-center">
@each('view.name', $records, 'record', 'view.empty')
</div>