5中将UUID用作主键

5中将UUID用作主键

本文介绍了在Laravel 5中将UUID用作主键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建具有主键的表,该主键是定义为binary(16)的UUID,而不是默认的自动递增id字段.

I'm trying to create tables that will have a primary key which is a UUID defined as binary(16) instead of the default auto-incrementing id field.

我已经设法通过DB::statement使用原始SQL语句创建了迁移,如下所示:

I've managed to create migrations using raw SQL statements though DB::statement like so:

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;");

但是,我无法使模型正常工作.我已经在此处中使用了该教程.我已经这样定义了我的模型:

However, I have trouble getting the model working. I've followed the tutorial available here. I've defined my model like so:

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();
    }
}

,其中UuidWebpatser\Uuid的别名.

我遇到的一个问题是,我无法如本教程中所述从Eloquent派生UuidModel.实际上,我没有看到Eloquent类.我是从Model派生的.我猜该教程是用Laravel 4编写的.

One problem, I'm having is I cannot derive UuidModel from Eloquent as explained in the tutorial. In fact I don't see an Eloquent class. I'm deriving from Model instead. I am guessing the tutorial was written in Laravel 4.

我希望能在Laravel 5中使用UUID作为主键来实现表方面的帮助.

I would appreciate help in implementing tables with UUIDs as primary keys in Laravel 5.

所以,如果我这样定义我的班级:

EDIT 1:So, if I define my class like so:

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行,则会出现以下错误:

If I remove the use Illuminate\Database\Eloquent line, I get the following error:

PHP Fatal error:  Class 'App\Eloquent' not found in /home/vagrant/transactly/app/UuidModel.php on line 8

修改2:我发现创建UuidModel实例时永远不会调用static::creating事件.

Edit 2:I have discovered that the static::creating event is never called for when instances of UuidModel are created.

我尝试在AppServiceProvider中设置creating事件侦听器,但这并未被调用.有趣的是,常规的Laravel生成的模型User也不调用creating事件.

I tried setting up the creating event listener in AppServiceProvider but that's not being called as well. Interestingly, the creating event is not called for a regular Laravel generated model User either.

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(){}

}

推荐答案

所以,我得到的东西就像一种魅力(未经测试的单元测试):

So, I got the thing working like a charm (not tested unit testing):

  1. class UuidModel extends Eloquent是较旧的(Laravel 4)构造.我们在Laravel 5中使用class UuidModel extends Model
  2. 解决方案是移动

  1. class UuidModel extends Eloquent is an older (Laravel 4) construct. We use class UuidModel extends Model in Laravel 5
  2. The solution was to move the

UuidModel::creating(function ($model) {
    echo "Creating Uuid Model...\n";
    $model->{$model->getKeyName()} = (string)$model->generateNewId();
});

AppServiceProvider::boot()EventServiceProvider::boot().无需其他更改.一切都按预期进行.

from AppServiceProvider::boot() to EventServiceProvider::boot(). No other changes were required. Everything worked as expected.

我仍然不知道为什么(2)不能在EventServiceProvider中工作,而不能在AppServiceProvider中工作,如官方文档.但是从名称来看,这也许就是它的本意.

I still don't know why (2) works in EventServiceProvider and not in AppServiceProvider as explained in the official docs. But judging from the name, that's perhaps the way it was meant to be.

这篇关于在Laravel 5中将UUID用作主键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 09:58