Laravel Relationship Events

Laravel Relationship Events

Laravel Relationship Events is a package by Viacheslav Ostrovskiy that adds extra model relationship events. This package comes with the following traits that are used to register listeners on a model’s boot() method:

  • HasOneEvents
  • HasBelongsToEvents
  • HasManyEvents
  • HasBelongsToManyEvents
  • HasMorphOneEvents
  • HasMorphToEvents
  • HasMorphManyEvents
  • HasMorphToManyEvents
  • HasMorphedByManyEvents

And from the above traits, here’s an example of a few events on a Country model that has many Users using the HasManyEvents trait:

namespace App\Models;

use App\User;
use Chelout\RelationshipEvents\Concerns\HasManyEvents;
use Illuminate\Database\Eloquent\Model;

class Country extends Model
{
    use HasManyEvents;

    protected $fillable = [
        'name',
    ];

    public function users()
    {
        return $this->hasMany(User::class);
    }

    public static function boot()
    {
        parent::boot();

        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}.");
        });
    }
}

And the inverse of the relationship with this package might look like the following:

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);
    }

    protected static function boot()
    {
        parent::boot();

        static::belongsToAssociating(function ($relation, $related, $parent) {
            Log::info("Associating country {$parent->name} with user.");
        });

        static::belongsToAssociated(function ($relation, $related, $parent) {
            Log::info("User has been assosiated with country {$parent->name}.");
        });
    }
}

Using an overloaded associate() method, you can fire two events belongsToAssociating and belongsToAssociated:

$country = App\Models\Country::first();

$user = factory(User::class)->create([
    'name' => 'John Smith',
]);

// Assosiate user with country
// This will fire belongsToAssociating and belongsToAssociated events
$user->country()->associate($country);

Learn More

The package has documentation for each trait and association type. Check out the package on GitHub at chelout/laravel-relationship-events.


Filed in: Laravel Packages / Eloquent


Newsletter

Join the weekly newsletter and never miss out on new tips, tutorials, and more.

Laravel News Partners

Laravel Jobs

Senior PHP/Laravel Developer: Your Dream Work Environment
Remote
iPhone Photography School
In-house Laravel Developer.
Gold Coast / Australia
MXstore
Laravel Developer
Oak Brook, IL
Tidal Commerce
Senior Backend Engineer
Santa Monica only
Saatchi Art
Senior Laravel Developer
San Francisco
Stitch Labs
Senior Software Developer
South Jordan, UT
Lendio
Full-Stack Developer
Paris, France
Wingly