当我在 laravel 中更新商店 table 时,如何解决“事件侦听器”问题?

How can I fix the `Event Listener` problem when I update the shop table in laravel?

现在我需要向商店已激活的用户发送消息。并且还给他们一个仪表板来添加新产品。

Goal: When in shops table the value of column is_active is made to active from inactive then I need to fire the email to user.

Shop.php

public function seller()    //user --> seller
{
    return $this->belongsTo(User::class, 'user_id');
}

I need observer class so I can find all these information on documentation in event section of Eloquent.

第 1 步

运行 下面的命令为商店模型

创建观察者 class
~$ php artisan make:observer ShopObserver --model=Shop

ShopObserver.php

<?php

namespace App\Observers;

use App\Shop;

class ShopObserver
{
    /**
     * Handle the shop "created" event.
     *
     * @param  \App\Shop  $shop
     * @return void
     */
    public function created(Shop $shop)
    {
        //
    }

    /**
     * Handle the shop "updated" event.
     *
     * @param  \App\Shop  $shop
     * @return void
     */
    public function updated(Shop $shop)
    {
        //
    }

    /**
     * Handle the shop "deleted" event.
     *
     * @param  \App\Shop  $shop
     * @return void
     */
    public function deleted(Shop $shop)
    {
        //
    }

    /**
     * Handle the shop "restored" event.
     *
     * @param  \App\Shop  $shop
     * @return void
     */
    public function restored(Shop $shop)
    {
        //
    }

    /**
     * Handle the shop "force deleted" event.
     *
     * @param  \App\Shop  $shop
     * @return void
     */
    public function forceDeleted(Shop $shop)
    {
        //
    }
}

第 2 步

在此之前,我们需要告诉 Laravel 您需要在与 Shop 相关的模型事件更新时使用此 class。要注册观察者,请在您希望观察的模型上使用 observe 方法。您可以在您的服务提供商之一的引导方法中注册观察者。在本例中,我们将在 AppServiceProvider 中注册观察者:

转到AppServiceProvider

AppServiceProvider.php

use App\Shop;
use App\Observers\ShopObserver;
public function boot()
{
    Shop::observe(ShopObserver::class);
}

第 3 步

ShopObserver.php

public function updated(Shop $shop)
{
    dd($shop);
}

SO when I update the is_active column to active from inactive then this doesn't work.

I mean the it should call the update function. But this function is not called.

I can't figure out the problem.

ShopController.php

public function update(Request $request, Shop $shop)
    {
        Shop::where('id', $request->shop_id)
            ->update([
                'is_active' => $request->is_active,
                'description' => $request->description,
                'location_id' => $request->location
            ]);

        return Redirect::route('dashboard.shops');
    }

你们更新Shop模型还是User模型?注意,您订阅了 Shop 模型。

建议: 尽量避免观察者,因为它们会向请求流引入一些 magic。 我更喜欢使用事件和事件监听器来完成这样的工作。 https://laravel.com/docs/7.x/events

如果您查看文档,这称为批量更新,因为不会检索模型,因此不会触发事件。您应该先找到商店,然后像这样更新其详细信息。

$updatingShop = Shop::where('id', $request->shop_id)->first();

if($updatingShop) {
   $updatingShop->update([
            'is_active' => $request->is_active,
            'description' => $request->description,
            'location_id' => $request->location
        ]);
}

只需使用控制器中的 $shop update 方法来更新

public function update(Request $request, Shop $shop)
{
    $shop
        ->update([
            'is_active' => $request->is_active,
            'description' => $request->description,
            'location_id' => $request->location
        ]);

    return Redirect::route('dashboard.shops');
}

这将触发 observer class

问题是您在模型本身的位置使用它,这是一个批量更新,不会触发观察者

#编辑 如果您希望观察仅在 is_active 字段上工作 你应该编辑 在您的观察中 class 添加:

public function updated(Shop $shop)
{
  if($shop->isDirty('is_active')){
    // add your code
  }
}

在观察者的updated方法中,您可以将旧值与新值进行比较。 另外,我的建议是在那里使用 event/listener methodology 这样你就可以得到类似这样的东西:

/**
 * Handle the User "updated" event.
 *
 * @param  \App\Shop  $shop
 * @return void
 */
public function updated(Shop $shop)
{
    if ($shop->is_active === 'active' 
        && $shop->is_active !== $shop->getOriginal('is_active')) {

        // you can make quick and dirty way here
        // but correct and well done job would be if you set event/listener
        event(new ShopUpdatedToActive());
    }
}

您始终可以使用 this trait 中的一些方法检查旧值(isDirtyisCleanwasChangedhasChangesgetOriginal等)