Laravel比较模型和强制转换属性

s3fp2yjn  于 2023-08-08  发布在  其他
关注(0)|答案(1)|浏览(84)

我正在一个Laravel 10应用程序中工作,并正在构建一个通知特性,该特性旨在当各种模型上的重要列发生变化时通知用户。我已经建立了一个包含这些方法的全局模型观察器,当模型更新时,我想将原始模型与当前模型进行比较。
我的问题是getAttributes()没有在我的模型上转换我的列,例如,我的Buyer模型确实定义了一个正确的casts属性 (我们可以从getOriginal()中看到这一点)
如何确保正确转换/比较值:

<?php

namespace App\Observers;

use Illuminate\Support\Facades\Log;
use App\Jobs\ProcessModelObserver;
use Carbon\Carbon;
use Exception;

class GlobalModelObserver
{
    /**
     * Handle the User "created" event.
     */
    public function created($model): void
    {
        try {
            ProcessModelObserver::dispatch($model, $model->id, 'created', Carbon::now());
        } catch (Exception $e) {
            // ...
        }
    }

    /**
     * Handle the User "updated" event.
     */
    public function updated($model): void
    {
        try {
            $originalAttributes = $model->getOriginal();
            $currentAttributes = $model->getAttributes();

            $columnsToExclude = [
                'id',
                'description',
                'is_favourited',
                'last_used_at',
                'updated_at',
                'created_at',
                'type',
                'last_built_at',
                'last_successful_build_at',
                'last_failed_build_at',
                'slug'
            ];

            $originalAttrs = collect($model->getOriginal())->reject(function ($value, $key) use ($columnsToExclude) {
                return in_array($key, $columnsToExclude);
            })->sort()->all();

            $currentAttrs = collect($model->getAttributes())->reject(function ($value, $key) use ($columnsToExclude) {
                return in_array($key, $columnsToExclude);
            })->sort()->all();

            $numDifferences = count(collect($originalAttrs)->diffAssoc(collect($currentAttrs))->toArray());

            // only dispatch if there are differences
            if ($numDifferences > 0) {
                ProcessModelObserver::dispatch($model, $model->id, 'updated', Carbon::now(), [
                    'model' => [
                        'original' => collect($originalAttrs)->toArray(),
                        'current' => collect($currentAttrs)->toArray()
                    ]
                ]);
            }

        } catch (Exception $e) {
            Log::debug("cannot send update notification", [
                'e' => $e->getMessage(),
                'f' => $e->getFile(),
                'l' => $e->getLine()
            ]);
        }
    }

    /**
     * Handle the User "deleted" event.
     */
    public function deleted($model): void
    {
        try {
            ProcessModelObserver::dispatch($model, $model->id, 'deleted', Carbon::now());
        } catch (Exception $e) {
            // ...
        }
    }

    /**
     * Handle the User "force deleted" event.
     */
    public function forceDeleted($model): void
    {
        try {
            ProcessModelObserver::dispatch($model, $model->id, 'deleted', Carbon::now());
        } catch (Exception $e) {
            // ...
        }
    }
}

字符串
此代码输出以下JSON:

{
   "model":{
      "original":{
         "is_default":false,
         "dedupe_is_enabled":false,
         "dedupe_value":0,
         "dedupe_accepts":false,
         "deleted_at":null,
         "user_id":1,
         "company_id":1,
         "product_id":1,
         "name":"TUK",
         "is_enabled":true,
         "dedupe_period":"days"
      },
      "current":{
         "is_default":0,
         "dedupe_is_enabled":0,
         "dedupe_value":0,
         "dedupe_accepts":0,
         "deleted_at":null,
         "user_id":1,
         "company_id":1,
         "product_id":1,
         "is_enabled":1,
         "name":"TUK",
         "dedupe_period":"days"
      }
   }
}


请问我需要换些什么?

ia2d9nvy

ia2d9nvy1#

您可以从在模型上实现接口开始

class User extends Model implements ListensForChanges {

  public function excludeFromListener(): array
  {
    return [
      // fields to exclude for each model
    ];
  }
}

字符串
我们可以这样更新全局观察器:

public function updated($model): void
{
  if ($model instanceof ListensForChanges) {
    $changes = Arr::except($model->getDirty(), $model->excludeFromListener())
  }
}

相关问题