当我在 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
- 现在我们有
DealOcean\app\Observers\ShopObserver.php
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 中的一些方法检查旧值(isDirty
、isClean
、wasChanged
、hasChanges
、getOriginal
等)
现在我需要向商店已激活的用户发送消息。并且还给他们一个仪表板来添加新产品。
Goal: When in
shops
table the value of columnis_active
is made toactive
frominactive
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
- 现在我们有
DealOcean\app\Observers\ShopObserver.php
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 toactive
frominactive
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 中的一些方法检查旧值(isDirty
、isClean
、wasChanged
、hasChanges
、getOriginal
等)