Laravel Relationship Events


Laravel Packages
/
July 09, 2018

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.

via Laravel News
Laravel Relationship Events