3
votes

Now I need to send message to User whose shop is activated. And also give them a dashboard to add new products.

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.

Step 1

Run below command to Create observer class for Shop Model

~$ php artisan make:observer ShopObserver --model=Shop
  • Now we have 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)
    {
        //
    }
}

Step 2

Before doing that, we need to tell Laravel that you need to use this class whenever model events related to Shop is updated. To register an observer, use the observe method on the model you wish to observe. You may register observers in the boot method of one of your service providers. In this example, we'll register the observer in the AppServiceProvider:

Go to AppServiceProvider

AppServiceProvider.php

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

Step 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');
    }
4
How do you updating it in code (controller)? Edit question with that code of how user/application sets is_active field to active.Tpojka
I have added that method in last section. Have a look bro....user14009834
I need to enter the update method observer first.user14009834
I don't think accepted answer solves your main question and that is "to check if is_active field has been changed to active". I made an answer of how just that can be achieved.Tpojka

4 Answers

1
votes

If you take a look at the docs, this is called mass update because the models are not retrieved so events are not fired. You should find the shop first then update its details like this.

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

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

In updated method of observer you can compare old value with new value. Also, my suggestion would be to use event/listener methodology there so you can have something similar to this:

/**
 * 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());
    }
}

You can always check old values with some of methods from this trait (isDirty, isClean, wasChanged, hasChanges, getOriginal etc.)

-1
votes

Do you update the Shop model or the User model? Pay attention, you subscribed to the Shop model.

Advice: Try to avoid Observers, as they introduce some magic to the requests flow. I prefer to use Events and Event Listeners to do such a job. https://laravel.com/docs/7.x/events

-1
votes

just use the $shop in your controller update method to 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');
}

this will fire the observer class

the problem that you are using where on the model it self and that is a mass update, that will not fire the observer

#edit if you want the observe to work only on the is_active field you should edit in your observe class add that:

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