Closed wilocampo closed 3 years ago
In your User model add:
use Ramsey\Uuid\Uuid;
protected $appends = [
'uuid',
];
public function getUuidAttribute()
{
return Uuid::fromBytes($this->attributes['uuid']);
}
or convert the uuid binary to string directly in use:
use Ramsey\Uuid\Uuid;
static::creating(function ($model) {
$model->created_by = Uuid::fromBytes(\Auth::User()->uuid);
});
In your User model add:
use Ramsey\Uuid\Uuid; protected $appends = [ 'uuid', ]; public function getUuidAttribute() { return Uuid::fromBytes($this->attributes['uuid']); }
Hi,
Thanks for the response.
I tried it but still same error occurs.
This is my User model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
/* UUID */
use Dyrynda\Database\Support\GeneratesUuid;
use Dyrynda\Database\Casts\EfficientUuid;
use Ramsey\Uuid\Uuid;
class User extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
use GeneratesUuid;
protected $uuidVersion = 'ordered';
public function getUuidAttribute()
{
return Uuid::fromBytes($this->attributes['uuid']);
}
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
'two_factor_recovery_codes',
'two_factor_secret',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
'uuid' => EfficientUuid::class,
];
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = [
'profile_photo_url',
'uuid',
];
}
And my user table migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->efficientUuid('uuid')->index();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable();
$table->text('profile_photo_path')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
And regarding this
or convert the uuid binary to string directly in use:
use Ramsey\Uuid\Uuid; static::creating(function ($model) { $model->created_by = Uuid::fromBytes(\Auth::User()->uuid); });
Setting the created_by in my trait works, so I did not converted the uuid to bytes. It saves data perfectly on my table.
I don't know where the issue lies, but after writing to the database, it produces an error
Below is the screenshot of the items table. The data is actually saved correctly. But after that, there is an error.
Can you create a new repository with the bare minimum to reproduce this?
try calling the toString()
method
in method 1:
public function getUuidAttribute()
{
return Uuid::fromBytes($this->attributes['uuid'])->toString();
}
in method 2:
static::creating(function ($model) {
$model->created_by = Uuid::fromBytes(\Auth::User()->uuid)->toString();
});
I finally fixed it. The problem was very simple.
The issue was Eloquent assumes the primary key to be incrementing. Since I am using id as uuid as my primary key in my Item model, adding the following line to the model removes the error.
public $incrementing = false;
I would be helpful if we can add this to the docs for those who will use UUID as primary key.
Thank you everyone.
I've added a note to the readme about the above. Thanks @wilocampo!
I've added a note to the readme about the above. Thanks @wilocampo!
Thank you for this.
Could you please also explain why it's not recommended to use efficient UUID as primary key? Because I'm starting to use UUID exactly in this way. To achieve the ability to create models on multiple independent sources and sync it then.
If you've got multiple database servers and you're syncing across, you typically want to offset the auto incrementing IDs by however many servers you have anyway. For simplicity, if you have two servers, you'd have one auto incrementing odd values (1, 3, 5, etc.) and the other even values (2, 4, 6, etc.) so that you don't have primary key collisions, handles multi-master, etc.
Using a combination of incrementing ID and UUID provides for more efficient queries at scale (from the readme) - https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
I have an issue with a newly-created project.
When I save a new model, this error occurs but the record is saved in the database.
Ramsey\Uuid\Exception\InvalidUuidStringException Invalid UUID string: 0
This is my migration:
This is my Item model:
My RecordSignature Trait:
This is my livewire component:
and my blade if it helps:
I cannot find where the issue lies, because I have tried this, third time now on a new laravel installation, this time with only the laravel-efficient-uuid and laravel-model-uuid packages installed (besides jetstream).
Please help.
This is my composer.json