我尝试创建的表格的主键是一个UUID,定义为binary(16)
,而不是默认的自动递增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;");
但是,我无法让模型正常工作。我已经按照可用的教程here进行了操作。我已经定义了我的模型:
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
事件。
我尝试在creating
中设置AppServiceProvider
事件监听器,但也没有被调用。有趣的是,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(){}
}
答案 0 :(得分:2)
所以,我觉得这个东西就像一个魅力(没有经过测试的单元测试):
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
中工作,正如官方docs中所解释的那样。但从名称来看,这可能是它的意图。
答案 1 :(得分:2)
将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;
无论如何,希望这有助于某人: - )
答案 2 :(得分:0)
这是一种不使用事件的快速解决方案。
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 {
}
答案 3 :(得分:-1)
也尝试使用此包将自动生成并在您的模型中指定UUID字段,也可以通过UUID键显示和更新。