[英]Using a UUID as primary key with Laravel 5
我正在嘗試創建具有主鍵的表,該主鍵是定義為binary(16)
的UUID,而不是默認的自動遞增id
字段。
我設法使用原始SQL語句創建遷移雖然DB::statement
如下:
DB::statement("CREATE TABLE `binary_primary_keys` (
`uuid` binary(16) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;");
但是,我無法讓模型正常工作。 我按照這里提供的教程進行了操作 。 我已經定義了我的模型:
class UuidModel extends Model
{
public $incrementing = false;
public $primaryKey = 'uuid';
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot()
{
parent::boot();
/**
* Attach to the 'creating' Model Event to provide a UUID
* for the `id` field (provided by $model->getKeyName())
*/
static::creating(function ($model) {
$model->{$model->getKeyName()} = (string)$model->generateNewId();
echo($model->{$model->getKeyName()});
});
}
/**
* Get a new version 4 (random) UUID.
*/
public function generateNewId()
{
return Uuid::generate();
}
}
其中Uuid
是Webpatser\\Uuid
的別名。
一個問題,我有是我不能獲得UuidModel
從Eloquent
作為教程解釋。 事實上,我沒有看到一個Eloquent
課程。 我是從Model
衍生出來的。 我猜這個教程是用Laravel 4編寫的。
我很感激幫助實現將UUID作為Laravel 5主鍵的表。
編輯1:所以,如果我這樣定義我的類:
use Illuminate\Database\Eloquent
class UuidModel extends Eloquent { ... }
我收到以下錯誤:
PHP Fatal error: Class 'Illuminate\Database\Eloquent' not found in /home/vagrant/transactly/app/UuidModel.php on line 8
如果我刪除use Illuminate\\Database\\Eloquent
行,我會收到以下錯誤:
PHP Fatal error: Class 'App\Eloquent' not found in /home/vagrant/transactly/app/UuidModel.php on line 8
編輯2:我發現在static::creating
UuidModel
實例時永遠不會調用static::creating
事件。
我嘗試在AppServiceProvider
設置creating
事件監聽器,但是也沒有調用它。 有趣的是, creating
事件不是為常規Laravel生成的模型User
調用的。
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
/**
* Attach to the 'creating' Model Event to provide a UUID
* for the `id` field (provided by $model->getKeyName())
*/
echo "Booting...\n";
UuidModel::creating(function ($model) {
echo "Creating Uuid Model...\n";
$model->{$model->getKeyName()} = (string)$model->generateNewId();
});
User::creating(function($user){
echo "Creating User Model...";
$user->name = 'Forced Name in boot()';
});
}
public function register(){}
}
所以,我得到的東西就像一個魅力(沒有經過測試的單元測試):
class UuidModel extends Eloquent
是一個較舊的(Laravel 4)構造。 我們在Laravel 5中使用class UuidModel extends Model
解決方案是移動
UuidModel::creating(function ($model) { echo "Creating Uuid Model...\\n"; $model->{$model->getKeyName()} = (string)$model->generateNewId(); });
從AppServiceProvider::boot()
到EventServiceProvider::boot()
。 無需其他更改。 一切都按預期工作。
我仍然不知道為什么(2)在EventServiceProvider
工作,而不是在官方文檔中解釋的AppServiceProvider
中。 但從名稱來看,這可能是它的意圖。
將36chr UUID存儲為二進制(16)的想法怎么樣:
IMO 在沒有Laravel生成UUID方面有一個優勢 。 也就是說,如果新記錄(將來的某一天)從應用程序外部插入到數據庫中,則可以正確填充UUID字段。
(此觸發器使DataBase服務器完成每次插入新客戶時生成UUID的工作)
<?php namespace MegaBank\HighInterestLoans\Updates;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class MigrationTriggerForCustomers extends Migration
{
public function up()
{
DB::unprepared('CREATE TRIGGER before_insert_customers
BEFORE INSERT ON
`megabank_highinterestloans_customers`
FOR EACH ROW
SET new.uuid = UNHEX(REPLACE(UUID(), "-","");');
}
public function down()
{
DB::unprepared('DROP TRIGGER `before_insert_customers`');
}
}
最后,如果您想獲得UUID的人類可讀版本,請執行以下操作:
SELECT HEX(UUID) FROM customers;
無論如何,希望這有助於某人:-)
這是一種不使用事件的快速解決方案。
UUidModel.php
<?php namespace App;
use \Illuminate\Database\Eloquent\Model;
use \Illuminate\Database\Eloquent\Builder;
class UuidModel extends Model
{
/**
* Insert the given attributes and set the ID on the model.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param array $attributes
* @return void
*/
protected function insertAndSetId(Builder $query, $attributes)
{
$keyName = $this->getKeyName();
$id = $attributes[$keyName] = $this->generateNewId();
$query->insert($attributes);
$this->setAttribute($keyName, $id);
}
/**
* Get a new version 4 (random) UUID.
*/
public function generateNewId()
{
return 'uuid!!' ;// just for test
}
}
?>
模型示例Car.php
<?php namespace App;
class Car extends UuidModel {
}
也嘗試使用此包將自動生成並在您的模型中分配UUID字段,也可以通過UUIDs鍵顯示和更新。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.