作为程序员一定要保持良好的睡眠,才能好编程

Eloquent 模型可以触发多种事件

发布时间:2021-01-16



Eloquent 模型可以触发多种事件,这允许你在模型的生命周期的各个关键点进行 hook 操作。你可以使用下面的方法进行 Hook:creating,created,updating,updated,saving,saved,deleting,deleted,restoring,restored。事件允许你轻松的在模型进行存储或更新操作时进行执行额外的操作。


基础用法

当一个新的模型首次进行存储操作时,会触发 creating 和 created 事件。如果模型已经存在于数据库中,并且调用 save 方法,那么 updating / updated 事件将会被触发。事实上,在这两种情况下,saving 和 saved 事件都会被触发。


举个示例,让我们在服务提供者中定义一个 Eloquent 事件监听器。在我们的事件监听器中,我们将在给定的模型中调用 isValid 方法,当模型并没有通过验证时将返回 false。如果从 Eloquent 事件监听器中返回 false,那么将取消 save / update 操作:


业务需求:


1、当新增用户地址的时候,检测是否设置默认地址 如果设置了,则将其他值设为false

2、当更新用户地址的时候,检测是否设置了默认地址,如果设置了,则将其他值设为false



代码:


举例说明:

<?php

namespace App\Models\Inquiry;

use App\Core\Model;
use Bhc\Library\Util\Snowflake;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Log;

/**
 * 用户地址表
 * Class UserAddressModel
 * @date 2020/2/4 10:20
 */
class UserAddressModel extends Model
{
    protected $table = 'user_address';

    protected $primaryKey = 'pkid';

    protected $keyType = 'string';

    protected $connection = 'ehosp';

    const CREATED_AT = 'gmt_created';

    const UPDATED_AT = 'gmt_modified';

    protected $hidden = [
        'pkid'
    ];

    protected $casts = [
        'id' => 'string',
    ];

    /**
     * 启动加载
     *
     * @date   2019-09-19 15:48:03
     */
    protected static function boot()
    {
        parent::boot();

        /** 增加全局作用域 */
        static::addGlobalScope('deleted', function (Builder $query) {
            $query->where('is_deleted', '=', '0');
        });
        
        self::creating(
            function ($model) {
                $model->id = Snowflake::generateId();
                //判断一下 一个用户只有一个默认地址
                if ($model->default) {
                    self::query()->where('user_id', '=', $model->user_id)->update(['default' => 0]);
                }
            }
        );


        /**
         * 'pdated,saving,saved
         */

        /** 更新 */
        self::updated(function ($model) {

            if ($model->default) {
                self::query()->where('user_id', $model->user_id)->where('id', '!=',
                    $model->id)->update(['default' => 0]);
            }
        });

        /**
         * 新增纪录生成雪花ID或更新
         */
        self::saved(
            function ($model) {
                if (!$model->id) {
                    $model->id = Snowflake::generateId();
                }
                if ($model->default) {
                    Log::info('test saveing nei' . $model->default);
                    self::query()->where('user_id', $model->user_id)->where('id', '!=',
                        $model->id)->update(['default' => 0]);
                }
            }
        );

    }


}



UserAddressService.php


<?php

namespace App\Services\Inquiry;

use App\Core\Service;
use App\Exceptions\ApiException;
use App\Library\StatusCode;
use App\Models\Inquiry\UserAddressModel;

class UserAddressService extends Service
{
    /**
     * 更新地址
     * update
     * @param $id
     * @param array $param
     * @return bool|int
     * @date 2020/2/7 13:49
     */
    public function update($id, array $param)
    {
        return UserAddressModel::query()->where('id', $id)->firstOrNew([])->update($param);
    }

    /**
     * 添加地址
     * add
     * @param array $param
     * @return mixed
     *
     * @throws ApiException
     * @date 2020/2/7 13:49
     */
    public function add(array $param)
    {
        $count = UserAddressModel::query()->where('user_id', '=', $param['user_id'])->get()->count();
        if ($count >= 20) {
            throw new ApiException('常用地址不能20,请删除不常用地址重新添加',StatusCode::USER_ADDRESS_GT_BIG_LENGTH);
        }
        $result = UserAddressModel::query()->create($param);

        return $result->id;
    }

    /**
     * 根据where条件获取地址列表
     * getList
     * @param array $where
     * @param array $fields
     * @param $pageSize
     * @param $pageNumber
     * @return DefaultPage
     *
     * @date 2020/2/7 13:48
     */
    public function getList(array $where, array $fields, $pageSize, $pageNumber)
    {
        $fields || $fields = '*';
        $result = UserAddressModel::getQuery($where)->latest('default')->paginate($pageSize, $fields, 'pageNumber',
            $pageNumber);
        return new DefaultPage(collect($result->items())->toArray(), $result->total(), $pageNumber, $pageSize);
    }

    /**
     * 获取一个地址信息
     * getOne
     * @param $id
     * @param array $fields
     * @return array
     *
     * @date 2020/2/7 13:47
     */
    public function getOne($id, array $fields)
    {
        return UserAddressModel::query()->where('id', $id)->firstOrNew([])->toArray();
    }

    /**
     * 获取当前用户的默认地址
     * getDefaultAddress
     * @param $userId
     * @param array $fields
     * @return array
     *
     * @date 2020/2/7 13:47
     */
    public function getDefaultAddress($userId, array $fields)
    {
        return UserAddressModel::query()->select($fields)->where('user_id', '=', $userId)->where('default', '=',
            1)->firstOrNew(
            []
        )->toArray();
    }

    /**
     * 将此id设为默认地址
     * setDefaultAddress
     * @param string $userId
     * @param $id
     * @return int
     *
     * @date 2020/2/9 17:17
     */
    public function setDefaultAddress(string $userId, $id)
    {
        return UserAddressModel::query()->where('user_id', '=', $userId)->where('id', '=',
            $id)->firstOrNew([])->update([
            'default' => '1'
        ]);
    }

    /**
     * 删除地址
     * delete
     * @param string $userId
     * @param $id
     * @return int
     *
     * @date 2020/2/9 17:27
     */
    public function delete(string $userId, $id)
    {
        return UserAddressModel::query()->where('user_id', $userId)->where('id',
            $id)->firstOrNew([])->update(['is_deleted' => '1']);
    }
}