В некоторых сценариях, например, когда клиенты могут повторно заказать заказ из прошлого, важно проверить, были ли изменены определенные поля после обновления, например, название или цена. Здесь может пригодиться трейт — назовем его HasChecksum. Эта черта позволяет легко генерировать контрольные суммы на основе определенных полей и сравнивать их, чтобы определить, были ли внесены изменения. В этой статье мы объясним, почему этот трейт полезен и как вы можете использовать его в своем приложении Laravel.

Чем полезен трейт HasChecksum?

Это может быть полезно в ситуациях, когда вы можете проверить, были ли изменены определенные поля в модели после обновления модели. Типичным примером этого является повторный заказ предыдущего заказа. В таком сценарии вы хотите уведомить клиента о любых изменениях в продукте и попросить его просмотреть заказ, прежде чем размещать его снова. Добавление подобной черты позволяет автоматически генерировать контрольную сумму на основе определенных значений полей в модели и сравнивать ее с исходной контрольной суммой, которую вы сохранили в заказе во время размещения заказа, чтобы вы могли определить, поля были изменены с момента размещения заказа.

Создайте новый файл HasChecksum.php и поместите его в каталог app\Traits:

namespace App\Traits;

trait HasChecksum
{

     /**
     * Observe the `saving`-event of the model and regenerate
     * the checksum each time the model has been saved.
     * @return void
     */
    public static function bootHasChecksum(): void
    {
        static::saving(function ($model) {
            $model->checksum = $model->generateChecksum();
        });
    }

    /**
     * Get the fields that are used to generate the checksum.
     * Override this function in the model where this trait
     * is used.
     * @return array
     */
    protected function checksumFields(): array
    {
        return [];
    }

    /**
     * Generate a checksum based on the given fields and
     * only take the first 10 characters of the hash.
     * @return string
     */
    protected function generateChecksum(): string
    {
        $values = collect($this->checksumFields())->map(
            fn($field) => $this->getAttribute($field)
        )->implode(':');

        return substr(md5($values), 0, 10);
    }
}

Как использовать трейт HasChecksum?

Чтобы использовать трейт HasChecksum, вам нужно добавить трейт к соответствующей модели в вашем приложении Laravel. Это можно легко сделать, добавив трейт в класс модели с помощью оператора «use» и добавив поле контрольной суммы в заполняемый массив, как показано в следующем примере:

namespace App\Models\Product;

use App\Traits\HasChecksum;

class Product extends Model 
{
    use HasChecksum;

    protected $fillable = [
      'checksum',
      'title',
      'price',
    ];
}

Конечно; также не забудьте добавить это поле в свой файл миграции, чтобы убедиться, что столбец «контрольная сумма» существует в вашей базе данных.

Затем вы должны переопределить метод `checksumFields()` признака в вашей модели, чтобы указать, какие поля следует использовать при создании контрольной суммы. Этот метод должен возвращать массив имен полей, как показано в следующем примере:

protected function checksumFields(): array
{
   return ['title', 'price'];
}

Затем метод `generateChecksum()` признака использует значения этих полей для генерации контрольной суммы.

В исходном примере кода значения полей объединяются двоеточием в качестве разделителя (что необязательно, так понятнее), а хэш MD5 результирующей строки усекается до 10 символов. Это может быть даже короче, поскольку оно не обязательно должно быть уникальным для каждой модели. Однако вы можете настроить логику метода `generateChecksum()` в соответствии с вашими конкретными требованиями.

Заключение

Контрольная сумма — полезный инструмент для проверки измененных полей после обновления в приложениях Laravel. Используя его в свойстве, вы можете легко генерировать контрольные суммы на основе определенных полей и сравнивать их, чтобы определить, были ли внесены изменения в несколько моделей. Это может быть особенно полезно в сценариях, где вам нужно уведомить пользователей об изменениях и попросить их просмотреть и подтвердить свои действия. Переместив логику генерации контрольной суммы в трейт в вашем приложении Laravel, вы можете повысить устойчивость и надежность своего кода.