【问题标题】:How to trigger a Model Observer in Laravel with the Maatwebsite/Excel package?如何使用 Maatwebsite/Excel 包在 Laravel 中触发模型观察器?
【发布时间】:2021-07-03 12:04:47
【问题描述】:

也许是一个简单的解决方案的问题,但我有几个小时试图弄清楚。 对不起我的英语不好......

我有一个管理产品、客户、订单、货币和其他东西的项目,这里最重要的是产品对数据库的操作,我使用 Laravel 8 和 Maatwebsite/excel 包来管理所有 xlsx 文件的导入有关产品的信息。

导入文件的过程运行良好,我有一个 ProductObserver 文件,它仅在我使用 CRUD 时触发事件,问题是这些事件在导入发生时不会触发。

我将发布我认为与流程相关的所有文件。

ProductObserver.php

     * Handle the Product "created" event.
     *
     * @param  \App\Models\Product  $product
     * @return void
     */
    public function created(Product $product)
    {
      if ($product->check_custom_price != 'on') {

        $currencies = Currency::all();

        foreach ($currencies as $currency) {
          ProductPrice::create([
              'product_id'    => $product->id,
              'currency_id'   => $currency->id,
              'price'         => $product->base_price * $currency->value,
              'status'        => 'A'
          ]);
          }

      }
    }

    /**
     * Handle the Product "updated" event.
     *
     * @param  \App\Models\Product  $product
     * @return void
     */
    public function updated(Product $product)
    {
      if($product->isDirty('base_price') && $product->check_custom_price != 'on'){
        ProductPrice::where('product_id', $product->id)->update([
          'status' => 'I',
        ]);

        $currencies = Currency::all();

        foreach ($currencies as $currency) {
          ProductPrice::create([
            'product_id'    => $product->id,
            'currency_id'   => $currency->id,
            'price'         => $product->base_price * $currency->value,
            'status'        => 'A'
        ]);
        }

      }
    }

这里的两个事件正如我所说的那样完美触发。

ProductImport.php

<?php

namespace App\Imports;

use App\Models\Product;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithUpserts;

class ProductsImport implements ToModel, WithHeadingRow, WithUpserts
{

    /**
     * @return string|array
     */
    public function uniqueBy()
    {
        return 'name';
    }

    /**
    * @param array $row
    *
    * @return \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new Product([
          'name'                => $row['name'],
          'base_price'          => $row['base_price'],
          'check_custom_price'  => $row['check_custom_price'],
        ]);
    }
}

如您所见,我有 ProductPrice, Currency, Product 模型和他们的表格来保存产品对每种货币的每个价格。

我错过了什么?

更新: EventServiceProviders.php

<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;

use App\Models\Product;
use App\Models\Currency;

use App\Observers\ProductObserver;
use App\Observers\CurrencyObserver;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        Product::observe(new ProductObserver);
        Currency::observe(new CurrencyObserver);
    }
}

观察者已注册,我对此没有任何问题,当我使用控制器操作创建或更新产品时,它就像魅力一样工作,感谢您的回答。

我很确定问题出在包保存模型的方式上。

在这个文档中:https://docs.laravel-excel.com/3.1/imports/model.html,他们说:
“将为您保存返回的模型。每一行将导致(至少)一次保存,并且还会触发模型事件。”

并且save 事件触发与创建或更新相同。

但是当导入时……什么都没有发生。

【问题讨论】:

    标签: php laravel maatwebsite-excel


    【解决方案1】:

    这里的问题是,在导入数据时,它使用了 ->insert() 方法,该方法确实会阻止触发任何事件。

    https://github.com/Maatwebsite/Laravel-Excel/issues/2220

    【讨论】:

    • 跟随你的链接我发现了一些其他的方法来使导入过程触发观察者。非常感谢。
    【解决方案2】:

    我看不出代码有什么问题,所以我想你可能忘记注册观察者了。

    use App\Models\Product;
    use App\Observers\ProductObserver;
    
    class EventServiceProvider extends ServiceProvider
    {
        /**
         * Register any events for your application.
         *
         * @return void
         */
        public function boot()
        {
            Product::observe(ProductObserver::class);
        }    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 2020-10-11
      • 2020-12-20
      • 2017-06-20
      • 2021-09-22
      相关资源
      最近更新 更多