Recently, I had to implement universal unique identifiers (UUIDs) in Laravel 7, and encountered some problems. I hope this post can help other people who are doing the same thing.
Advanced reasons for using UUIDs
A) They remove the ID number from your uniform resource locator, so users can't see how many specific objects your app has created. For example:
https://myapp.com/api/users/5
contrast:
https://myapp.com/api/users/0892b118-856e-4a15-af0c-66a3a4a28eed
B) They make ID numbers far more difficult to guess. This is good for security, but we may need to implement other technologies to prevent it.
Implementing UUIDs as primary key
How to change database migration
First of all, in database migration, you need to replace the currently auto incrementing ID field with UUIDs. You can also follow the following method: keep the auto increment ID and use UUID as an additional field in the table when the user presents the URL (in this case, you hide the ID in the model), but this is not what we can do here. Let's see what the hypothetical employees table looks like.
public function up() { Schema::create('employees', function (Blueprint $table) { $table->uuid('id')->primary; $table->string('name'); $table->string('email')->unique(); $table->string('work_location')->nullable(); $table->timestamps(); }); }
Here, notice that we replaced normal id() with uuid (); and made it the primary key.
Let's turn it into a trait
Next, we can implement the Laravel lifecycle hook to ensure that UUIDs are assigned when creating new instances of this model. We can write code directly in the model, but if you want to use UUID in multiple models, I suggest using trait (I learned this in this development article, thanks Dev). Trait basically allows you to create functionality and call it through the use keyword to use it in multiple models.
To create a new trail, create a \ app \ http \ trails \ folder (this is just my hobby, you can also put it in another location), and create a new file for the trail. We will call the file UsesUuid.php .
This is the specific code of trait:
<?php namespace App\Http\Traits; use Illuminate\Support\Str; trait UsesUuid { protected static function bootUsesUuid() { static::creating(function ($model) { if (! $model->getKey()) { $model->{$model->getKeyName()} = (string) Str::uuid(); } }); } public function getIncrementing() { return false; } public function getKeyType() { return 'string'; } }
Use \ Illuminate\Support\Str to easily generate UUIDs. The getIncrementing () method tells Laravel that the primary key of the model will not increase automatically (because we set false), while the getKeyType () method tells Laravel that the primary key of the model is of string type. The bootuseuuid () method allows us to use Laravel's powerful lifecycle hook. You can come here for more details. Basically our code can tell Laravel to set the UUID primary key for a new instance of the model when it is created!
Now we can easily implement this feature on the model using the use keyword.
<?php namespace App; use Illuminate\Database\Eloquent\Model; ... class Employee extends Model { ... use \App\Http\Traits\UsesUuid; ... }
Reference UUID as foreign key
To reference a UUID on a table as a foreign key, simply change the type of the foreign key field on the table. As follows
Schema::create('another_table', function(Blueprint $table) { $table->id(); $table->unsignedBigInteger('employee_id'); $table->string('some_field'); $table->foreign('employee_id') ->references('id') ->on('shifts') ->onDelete('cascade'); });
... we're referring to employee_ When the ID foreign key is used, an unsigned big integer data type is created, which is modified as follows:
Schema::create('another_table', function(Blueprint $table) { $table->id(); $table->uuid('employee_id'); $table->string('some_field'); $table->foreign('employee_id') ->references('id') ->on('shifts') ->onDelete('cascade'); });
That's easy! There is another thing...
UUID and polymorphism
You may find yourself referring to the model in a polymorphic relationship through your own actions or packages to be introduced. During migration, the table might look like this:
public function up() { Schema::create('some_package_table', function (Blueprint $table) { $table->bigIncrements('id'); $table->morphs('model'); ... } }
Here, the morphs () method creates two fields in the database, the model of the unsigned large integer type_ Model of ID and string type_ type. The problem is that our model now uses UUID s instead of incrementing integer IDS, so this will give you errors and display something like this:
Data truncated for column 'model_id' at row 1
We need model now_ The ID field to support our new UUID, which is of type CHAR (36). don't worry! Laravel makes it super simple, you don't have to do it manually. Just change the migration to:
public function up() { Schema::create('some_package_table', function (Blueprint $table) { $table->bigIncrements('id'); $table->uuidMorphs('model'); ... } }
For more PHP content, visit: