Laravel is trying to use uuid
field as foreign key. And I want to use foreign key with the field id
. Is there any option there?
Using this trait on Model. And then it is trying to use the uuid
as foreign key. But still I want to use id
as foreign key.
<?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();
});
}
}
CodePudding user response:
There is nothing special about this trait. You can make your own trait with id instead of uuid and everything will work fine.
CodePudding user response:
The issue came from methods getIncrementing()
and getKeyName()
. Laravel calls getKeyName()
in amount of built-in functions to interacts with relationships, also other actions like delete()
, route bindings, etc.
You should allow any models which uses this trait to custom the Primary key (PK), so that uuid
is only common column at all.
Your trait definition is force PK column as uuid
.
Below is my recommended for the trait
<?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();
});
}
}
If a model need to have uuid
as PK, for example Book
model
class Book extends Model
{
use UsesUuid;
public function isUuidAsPrimaryKey()
{
return true;
}
}
Please recheck the method isUuidAsPrimaryKey
. If it may not be overridden (due to conflict), then use a property instead.