Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel LastInsertId with UUID PK

I am attempting to use a UUID as a primary key using Laravel 4.

Not finding much info about this topic I decided to use a trigger in MySQL to set the id column with a value of UUID() on insert.

From what I have read, I need to set a var in the model of

public $incrementing = false;

In my migrations file I have something like this for each table:

//set default id to UUID, requires thread_stack in my.cnf to be 196k
function makeTrigger($tableName)
{
    DB::unprepared('CREATE TRIGGER '.$tableName.'_trigger_id BEFORE INSERT ON '.$tableName.' FOR EACH ROW SET NEW.id = UUID()');
}

$tableName = 'sites';
Schema::create($tableName, function($table)
{
    $table->string('id', 36)->primary();
    $table->string('name', 50);
    $table->string('development_url', 50);
    $table->string('production_url', 50);
    $table->boolean('launched')->default(0);
    $table->string('test');
    $table->timestamps();
    $table->softDeletes();
});
makeTrigger($tableName);

While I can insert a record like this that has a UUID, I cannot return the ID if $incrementing = false is set in the model.

If I remove that var and I am using a UUID, the id returned is 0. If I use increments('id') in the migrations file, I get the real id returned.

I am building an app that UUIDs for ids in the spec, so I am trying to figure out if this is possible in Laravel 4.

If I am unable to get that id back using

$user = User::create($userdata);

return $user->id;

then how will the id be used for relationships? (Same issue using $user->save();)

From what I understand Eloquent is expecting an auto_increment back, but it seems like there should be a way to get any id back.

Why won't this work?

Any insight into this area would be appreciated, as I can't seem to find any real documentation on this topic.

like image 463
Jazzy Avatar asked Jun 24 '13 16:06

Jazzy


1 Answers

I solved this by using the creating Event on the Model to add a new UUID when the Model gets saved. You can also find my solution on packagist.

class BaseModel extends Eloquent {

    /**
     * Indicates if the IDs are auto-incrementing.
     *
     * @var bool
     */
    public $incrementing = false;

    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function($model)
        {
            $model->{$model->getKeyName()} = (string)$model->generateNewId();
        });
    }

    /**
     * Get a new version 4 (random) UUID.
     *
     * @return \Rhumsaa\Uuid\Uuid
     */
    public function generateNewId()
    {
        return \Rhumsaa\Uuid\Uuid::uuid4();
    }

}
like image 99
r15ch13 Avatar answered Oct 24 '22 08:10

r15ch13