Laravel:停止使用UUID作为外键

mnemlml8  于 2022-11-18  发布在  其他
关注(0)|答案(2)|浏览(182)

Laravel试图使用uuid字段作为外键。我想使用id字段作为外键。有任何选择吗?
在Model上使用这个特性,然后它尝试使用uuid作为外键,但是我还是想使用id作为外键。

<?php

namespace App\Library;

use Ramsey\Uuid\Uuid;

trait UsesUuid
{
    /**
     * @return string
     */
    public function getKeyName()
    {
        return 'uuid';
    }

    /**
     * @return string
     */
    public function getKeyType()
    {
        return 'string';
    }

    /**
     * @return false
     */
    public function getIncrementing()
    {
        return false;
    }

    /**
     * @param $query
     * @param $uuid
     * @return mixed
     */
    public function scopeUuid($query, $uuid)
    {
        return $query->where($this->getUuidName(), $uuid);
    }

    /**
     * @return string
     */
    public function getUuidName()
    {
        return property_exists($this, 'uuidName') ? $this->uuidName : 'uuid';
    }

    /**
     * @return string
     */
    public function getRouteKeyName()
    {
        return property_exists($this, 'uuidName') ? $this->uuidName : 'uuid';
    }

    /**
     *
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            $model->{$model->getUuidName()} = Uuid::uuid4()->toString();
        });
    }
}
wf82jlnq

wf82jlnq1#

这个特质没有什么特别之处,你可以用id而不是uuid来制作自己的特质,一切都会很好地工作。

yiytaume

yiytaume2#

问题来自方法getIncrementing()getKeyName()。Laravel调用了大量内置函数getKeyName()来与关系进行交互,还调用了其他操作,如delete()、路由绑定等。
您应该允许任何使用此特征的模型自定义主键(PK),以便uuid是唯一的公共列。
您的特征定义是强制PK列为uuid
下面是我对这个特质的推荐

<?php

namespace App\Library;

use Ramsey\Uuid\Uuid;

trait UsesUuid
{
    /* Override this method to set `uuid` as PK */
    public function isUuidAsPrimaryKey()
    {
        return false;
    }

    /**
     * @return string
     */
    public function getKeyName()
    {
        return $this->isUuidAsPrimaryKey() ? $this->getUuidName() : $this->primaryKey;
    }

    /**
     * @return string
     */
    public function getKeyType()
    {
        return $this->isUuidAsPrimaryKey() ? 'string' : $this->keyType;
    }

    /**
     * @return false
     */
    public function getIncrementing()
    {
        return !$this->isUuidAsPrimaryKey();
    }

    /**
     * @param $query
     * @param $uuid
     * @return mixed
     */
    public function scopeUuid($query, $uuid)
    {
        return $query->where($this->getUuidName(), $uuid);
    }

    /**
     * @return string
     */
    public function getUuidName()
    {
        return property_exists($this, 'uuidName') ? $this->uuidName : 'uuid';
    }

    /**
     * @return string
     */
    public function getRouteKeyName()
    {
        return property_exists($this, 'uuidName') ? $this->uuidName : 'uuid';
    }

    /**
     *
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            $model->{$model->getUuidName()} = Uuid::uuid4()->toString();
        });
    }
}

如果一个型号需要有uuid作为PK,例如Book型号

class Book extends Model
{
    use UsesUuid;

    public function isUuidAsPrimaryKey()
    {
        return true;
    }
}

请重新检查方法isUuidAsPrimaryKey。如果无法覆写(因为恩怨),请改用属性。

相关问题