How to listen for changes on Eloquent MorphToMany pivot table

Viewed 303

I have 3 Models (Operator1, Operator2, Operator3) that all have a MorphToMany relationship to PaymentMethods. The relation/pivot table contains some additional information, specific to the single operator. Here is an example model:

class Operator1 extends Model
{
    /**
     * The payment methods of the operator.
     */
    public function paymentMethods()
    {
        return $this->morphToMany('App\PaymentMethod', 'payable')->withPivot([
            'deposit_time',
            'withdrawal_time',
            'deposit_fees',
            'withdrawal_fees',
        ]);
    }
}

I need to listen for changes on the pivot table. When working with BelongsToMany relations, I can use the ->using(aPivotModelClass::class) method to specify a custom pivot class model, where I then can listen for saving, saved, deleted, deleting, etc. eloquent events.

I am using the eventually package by altek to not have to do this for every pivot, but since I am using Laravel Nova, which doesn't fire the events provided by that package, I need to fire them manually. I do this like this:

use Illuminate\Database\Eloquent\Relations\Pivot as EloquentPivot;

abstract class Pivot extends EloquentPivot
{
    /**
     * @var string
     */
    public $relationName;

    /**
     * {@inheritDoc}
     */
    public static function boot()
    {
        parent::boot();

        static::saved(function (Pivot $model) {
            $model->pivotParent->firePivotEvent('attached', true, $model->relationName, [$model->attributes]);
        });

        static::deleted(function (Pivot $model) {
            $model->pivotParent->firePivotEvent('detached', true, $model->relationName, [$model->attributes]);
        });
    }
}

This all works so far in combination with BelongsToMany, but now I'm trying to use the ->using(SomePivotModel::class) method on a MorphToMany relation. That doesn't work and I get the following error:

local.ERROR: Call to undefined method App\Pivots\Payables::setMorphType() {"userId":1,"exception":"[object] (BadMethodCallException(code: 0): Call to undefined method App\\Pivots\\Payables::setMorphType() at /var/www/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php:50)

How could I listen for updates on MorphToMany pivot tables, without the eventually or similar packages?

Related: GitHub comment

1 Answers

I suspect that your SomePivotModel model extends Illuminate\Database\Eloquent\Relations\Pivot when it should instead extend Illuminate\Database\Eloquent\Relations\MorphPivot

Related