laravel-relationship-events icon indicating copy to clipboard operation
laravel-relationship-events copied to clipboard

Events do not fire when Nova UI is used.

Open greggh opened this issue 6 years ago • 22 comments
trafficstars

This package is great, does everything we need, except in Laravel Nova. When I use the Attach or Detach buttons on the Nova UI for any of my belongsToMany relationships, nothing fires, no events.

The same relationships with no code changes work great outside of Nova, and I get my events in my observer class for. In jobs running on the schedule, and even down in tinker on the command line. The events fire.

public function belongsToManyAttached($relation, Website $website, $ids)

and

public function belongsToManyDetached($relation, Website $website, $ids)

Website is the class I am observing.

greggh avatar Jan 21 '19 19:01 greggh

I'd like to help you, but i don't have Nova license 😔

chelout avatar Jan 22 '19 05:01 chelout

Hi, I got the same issues when using laravel-admin which is a CMS framework similar to Nova. Although I don't have a Nova license, I want to share my experience to fix this issues in laravel-admin and hope this may help you to find out the problem in Nova.

After few hours digging in laravel-admin source code, I found out the function which update relations and in this function, there is a switch() closure as below:

.
.
.
switch (get_class($relation)) {
                case Relations\BelongsToMany::class:
                case Relations\MorphToMany::class:
                    if (isset($prepared[$name])) {
                        $relation->sync($prepared[$name]);
                    }
                    break;
                case Relations\HasOne::class:
.
.
.

The problem is get_class($relation). When using laravel-relationship-events package, it will return Chelout\RelationshipEvents\BelongsToMany instead of Relations\BelongsToMany, although Chelout\RelationshipEvents\BelongsToMany inherits Relations\BelongsToMany, it still can't match any of the cases, thus no any update (sync in my case) and event fire.

So I change the logic a little bit, and it works prefectly. And I created a pull request to laravel-admin.

.
.
.
 switch (true) {
                case $relation instanceof Relations\BelongsToMany:
                case $relation instanceof Relations\MorphToMany:
                    if (isset($prepared[$name])) {
                        $relation->sync($prepared[$name]);
                    }
                    break;
                case $relation instanceof Relations\HasOne:
.
.
.

At this moment, I don't have any idea without changing the source code of laravel-admin. If @chelout find out any workaround, it would be great ! :smile:

JT501 avatar Feb 08 '19 08:02 JT501

Thanks for share @hallelujahbaby! But without Nova code i can't fix the problem 😢 Maybe @themsaid can help with a dev license? 😬

chelout avatar Feb 08 '19 19:02 chelout

@themsaid I'm sure you get requests all the time, but this would be amazing. None of the existing packages I can find actually fire these events when Nova is used. If @chelout had a license it could be fixed in this one. Would be a huge help.

greggh avatar Feb 11 '19 19:02 greggh

I see Nova using a Illuminate\Database\Eloquent\Relations\Pivot instance to do the pivot rescue. I guess that's why events don't get launched.

However, the events at the pivot update don't work that way either:

 Location::find(20993)->products()->first()->save();

Why is the event belongsToManyUpdatingExistingPivot not raised in this case?

f-liva avatar Feb 22 '19 11:02 f-liva

If it helps, this is what the Nova controller does when attaching a model into a morphedByMany relationship.

($pivot = $relationship->newPivot())->forceFill([
    $relationship->getForeignPivotKeyName() => $request->resourceId,
    $relationship->getRelatedPivotKeyName() => $request->input($request->relatedResource),
    $relationship->getMorphType() => $request->findModelOrFail()->{$request->viaRelationship}()->getMorphClass(),
        ]);

arall avatar Mar 04 '19 14:03 arall

Any news here?

f-liva avatar Apr 16 '19 08:04 f-liva

As i can see from comments above Nova works with pivot models and doesn't support normal relations, so many-to-many relations can't be supported by this package. Ofcourse we can change basic behavior of laravel's relations, but i don't want to miss miss compatibility.

chelout avatar May 07 '19 05:05 chelout

How would you do that?

f-liva avatar May 07 '19 07:05 f-liva

Maybe we can implement an adaptor or a Nova component for doing that without messing with this repo? But I have no much clue of how to do it...

arall avatar May 07 '19 07:05 arall

@fede91it I guess, it is possible to override laravel's methods like attach, detach, etc to use pivot models. @arall yeah, i guess we can try to write a component for Nova, but as i mentioned above i don't have license or even Nova code to do it.

chelout avatar May 07 '19 07:05 chelout

@chelout I might be able to provide you a license. If you're interested, could you reach me on Telegram? I'm using the same username as in here. Or email (my full name @ gmail.com).

arall avatar May 07 '19 07:05 arall

If necessary, I can sponsor the development of this additional feature.

f-liva avatar May 09 '19 07:05 f-liva

@fede91it Actually i tend not to change default logic of laravel's relation system, i tend to making Nova plug-in to support our package. If you would like to sponsor this package you can always reach me on telegram @slaffka_moscow

chelout avatar May 10 '19 16:05 chelout

Why we can't create a trait for the pivot models?

f-liva avatar May 11 '19 07:05 f-liva

Any updates on this?

arall avatar Nov 06 '19 13:11 arall

Came here because I was looking for the same functionality. Currently working on my Nova admin and this would solve a big issue.

gavinhewitt avatar Nov 15 '19 10:11 gavinhewitt

There are no updates on this topic. Sorry, guys.

chelout avatar Nov 15 '19 10:11 chelout

I did a proof of concept using Laravel native Pivot models events and works fine with Nova: https://github.com/arall/laravel-relationhip-events

arall avatar Aug 07 '20 14:08 arall

@arall yes, you right, it's possible with pivot events, but this package doesn't use them.

chelout avatar Aug 07 '20 16:08 chelout

bump?

riptin avatar Mar 24 '21 12:03 riptin

This is my workaround for this issue. hope it helps.

First, you should create a model for pivot table.

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphPivot;

class Taggable extends MorphPivot
{
    protected $table = 'taggables';
    public $incrementing = true;
}

Then, it's time to define this model to your morph relations

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphToMany;

class Tag extends Model
{
    public function products(): MorphToMany
    {
        return $this->morphedByMany(Product::class, 'taggable')->using(Taggable::class);
    }
}

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphToMany;

class Product extends Model
{
    public function tags(): MorphToMany
    {
        return $this->morphToMany(Tag::class, 'taggable')
            ->using(Taggable::class)
            ->withTimestamps();
    }
}

now you can create an observer for your Taggable model and it works perfectly fine with nova admin panel

mostafaznv avatar Aug 18 '21 09:08 mostafaznv