Laravel Model Relationships and Model Events
I am building a notification system for now and notifications are delivered via model events. Some of the notifications depend on what's going on with the model relationship.
Example: I have a project model that has one thing: many relationships with users,
public function projectmanager() {
return $this->belongsToMany('User', 'project_managers');
}
I want to track changes in this relationship in my design model events. At the moment I am doing this by doing the following:
$dirtyAttributes = $project->getDirty();
foreach($dirtyAttributes as $attribute => $value) {
//Do something
}
This is done in a ::updating
model event, but only looks at the attributes of the models, not any relational data, is it possible to compare and process old relational data and new relational data?
source to share
For this, you must use the observer class .
It's pretty simple and well stated in this SO answer , although this answer uses a slightly older method where the class itself has to call its observer. The documentation for the current version (5.3 from this answer) recommends registering a watcher with the app provider, which in your example would look something like this:
<?php
namespace App\Providers;
use App\Project;
use App\Observers\ProjectObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Project::observe(ProjectObserver::class);
}
}
To evaluate the differences between the new model and the values of the old values, which are still in a relational database, Laravel provides methods for both: getDirty()
and getOriginal()
.
So your observer will look something like this:
<?php
namespace App\Observers;
use App\Project;
class ProjectObserver
{
/**
* Listen to the Project updating event.
*
* @param Project $project
* @return void
*/
public function updating(Project $project)
{
$dirtyAttribtues = $project->getDirty();
$originalAttributes = $project->getOriginal();
// loop over one and compare/process against the other
foreach ($dirtyAttributes as $attribute => $value) {
// do something with the equivalent entry in $originalAttributes
}
}
}
source to share