chelout/laravel-relationship-events
Adds missing Eloquent relationship events to Laravel models. Use simple traits (HasOne/Many, BelongsTo/Many, Morph*) to listen for attach/detach/sync, saved/updated, and other relation lifecycle hooks with parent/related context and IDs/attributes.
User model belongs to many Role models
namespace App\Models;
use App\User;
use Chelout\RelationshipEvents\Concerns\HasBelongsToManyEvents;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use HasBelongsToManyEvents;
protected $fillable = [
'name', 'email', 'password', 'country_id',
];
public function roles()
{
return $this->belongsToMany(Role::class)
->withPivot('is_active');
}
}
Now we can use attach, detach, sync, toggle methods to update existing pivot:
// ...
$user = factory('App\User')->create();
// Attcha one role to user
// This will fire two events belongsToManyAttaching, belongsToManyAttached
$role = factory('App\Models\Role')->create();
$user->roles()->attach($role, ['is_active' => true]);
// Attach many roles to user
// This will fire two events belongsToManyAttaching, belongsToManyAttached
$roles = factory('App\Models\Role', 2)->create();
$user->roles()->attach(
$roles->mapWithKeys(function ($role) {
return [
$role->id => [
'is_active' => true,
],
];
})
->toArray()
);
// ...
Now we should listen our events, for example we can register event listners in model's boot method:
// ...
protected static function boot()
{
parent::boot();
static::belongsToManyAttaching(function ($relation, $parent, $ids) {
Log::info("Attaching roles to user {$parent->name}.");
});
static::belongsToManyAttached(function ($relation, $parent, $ids) {
Log::info("Roles has been attached to user {$parent->name}.");
});
}
// ...
Note: has additional query to get related ids
There is also inverse relation User belongs to Country
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Chelout\RelationshipEvents\Concerns\HasBelongsToEvents;
class User extends Model
{
use HasBelongsToEvents;
/**
* Get the country associated with the user.
*/
public function country()
{
return $this->belongsTo(Country::class);
}
}
Now we can use methods to assosiate Country with User and also update assosiated models.
// ...
// create user
$user = factory('App\User')->create();
// Getting random country
$country = App\Models\Country::inRandomOrder()->first();
// Saving user with specified country
// This will fire two events hasManySaving, hasManySaved
$country->users()->save($user);
// ...
Now we should listen our events, for example we can register event listners in model's boot method:
// ...
public static function boot()
{
parent::boot();
/**
* One To Many Relationship Events
*/
static::hasManySaving(function ($parent, $related) {
Log::info("Saving user's country {$parent->name}.");
});
static::hasManySaved(function ($parent, $related) {
Log::info("User's country is now set to {$parent->name}.");
});
}
// ...
Note: has additional query to get related Eloquent collection
How can I help you explore Laravel packages today?