Working with larger models, the interface where we interact with our models easily can become large and hard to read. If it’s possible, reorganizing some steps may keep cleaner our controllers, services or repositories we use.
About Eloquent events in general
Eloquent is the Active Record implementation of Laravel. It makes possible to work with models like never before. Next, to the beautiful and expressive syntax, it has many other powerful features. One of them is the ORM’s event system. We have the chance to listen a different kind of events and states. This is a superb spot to automate some logic in the background without touching our interfaces.
Laravel provides events, what almost cover the database actions of a model. The built-in events are: creating, created, saving, saved, deleting, deleted, updating, updated, restoring, restored. We can easily listen to these events and intercept them to modify whatever we want. As you see this event implementation can hook in before and after the transaction.
Refactoring logic using eloquent events
Let’s stick with an example to keep things clear. When an admin creates a user, we automatically want to give the user an API token. We can use our controller to handle the logic.
// app/Http/Controllers/UsersController.php <?php namespace App\Http\Controllers; use App\User; use Illuminate\Http\Request; class UserController extends Controller { public function store(Request $request) { $user = User::create($request->all() + [ 'api_token' => md5(str_random(10)), ]); return redirect()->route('users.show', $user); } }
The main problem with this, if we have many tasks to automate, our controller could be messy. Another reason not to do this, this function should not take place in the controller, it’s not the controller’s job to handle this logic.
This is the place when Eloquent’s event system comes in. In this example, we could listen to the creating method to attach a token to the user before saving to the database. All we have to do is extending our User model, with almost the same logic we implemented in the store method.
// app/User.php <?php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; protected static function boot() { parent::boot(); static::creating(function ($user) { $user->api_token = md5(str_random(10)); }); } }
After extending our model with an event listener, we can clean up our controller. The API token is now automatically filled behind the scenes.
If you are interested, you can read more about Laravel events here.