首页 > 解决方案 > 在 Laravel 8 中通过验证保护模型

问题描述

我有phones带字段的数据库表phone_number。我有一个模型电话。我想以固定格式(已清理)和填充phone_number(已验证)保存电话

代码中有很多地方需要我或我的同事保存手机。我不相信,他们都会费心检查是否phone_number填写了正确的格式。而且我不想指望前端 JS 验证或数据库NOT NULL检查,...

所以我认为清理和验证电话的最佳位置将是模型本身。

我怎样才能以最干净的方式在 Laravel 8.x 中做到这一点?

我在互联网上发现了很多这样的问题,但是提出的解决方案要么编写大量代码并将框架弯曲得令人作呕,要么人们根本没有抓住这个问题。

Mabye 我应该补充一点,我希望这会自动发生。因此,任何尝试$phone->save()Phone::create()以错误格式拨打电话的人最终都会收到 ValidationException

编辑 2:提供者/观察者 - 我在寻找正确的方向吗?

编辑 3:事件?所以在我的模型中,我应该这样做:

use Notifiable;

protected $dispatchesEvents = [
    'validating' => PhoneSanitize::class,
    'saving'     => PhoneValidate::class,
];

编辑 4:或者您认为在模型级别验证数据是一个坏主意?我读过这篇文章:

Nikola Poša - 自我验证域模型

在我看来这是个好主意。但是如何在 Laravel 中实现这一点?

标签: laravelvalidationsanitizationlaravel-8

解决方案


在模型级别验证数据是一个坏主意,因为验证逻辑更多的是关于表单请求。

话虽如此,您可以使用Eloquent Mutators来清理(甚至验证)您在模型中的输入。

namespace App\Models;

use Illuminate\Support\Facades\Validator;

class Phone extends Model
{
    // ...

    public function setPhoneNumberAttribute($value)
    {
        // Do your sanitization
        // ...

        // Do your validation
        Validator::make([
            'phone_number' => $value,
        ], [
            'phone_number' => ['required'], // Define your validation rules
        ])->validate();

        $this->attributes['phone_number'] = $value;
    }

    // ...
}

如果验证失败,Illuminate\Validation\ValidationException将抛出 并自动重定向用户,或者在 AJAX 请求的情况下,将返回 JSON 响应。


推荐阅读