laraveluuidlaravel-events

lararvel uuid as primary key


I'm trying to set an uuid as primary key in a Laravel Model. I've done it setting a boot method in my model as stablished here so I don't have to manually create it everytime I want to create and save the model. I have a controller that just creates the model and saves it in database.

It is saved correctly in database but when controller returns the value of the id is always returned with 0. How can I make it to actually return the value that it is creating in database?

Model

class UserPersona extends Model
{
    protected $guarded = [];

    protected $casts = [
        'id' => 'string'
    ];

    /**
     *  Setup model event hooks
     */
    public static function boot()
    {
        parent::boot();
        self::creating(function ($model) {
            $uuid = Uuid::uuid4();
            $model->id = $uuid->toString();
        });
    }
}

Controller

class UserPersonaController extends Controller
{
    public function new(Request $request)
    {
        return UserPersona::create();
    }
}

Solution

  • You need to change the keyType to string and incrementing to false. Since it's not incrementing.

    public $incrementing = false;
    protected $keyType = 'string';
    

    Additionally I have an trait which I simply add to those models which have UUID keys. Which is pretty flexible. This comes originally from https://garrettstjohn.com/articles/using-uuid-laravel-eloquent-orm/ and I added some small adjustments to it for issues which I have discovered while using it intensively.

    use Illuminate\Database\Eloquent\Model;
    use Ramsey\Uuid\Uuid;
    
    /**
     * Class Uuid.
     * Manages the usage of creating UUID values for primary keys. Drop into your models as
     * per normal to use this functionality. Works right out of the box.
     * Taken from: http://garrettstjohn.com/entry/using-uuids-laravel-eloquent-orm/
     */
    trait UuidForKey
    {
    
        /**
         * The "booting" method of the model.
         */
        public static function bootUuidForKey()
        {
            static::retrieved(function (Model $model) {
                $model->incrementing = false;  // this is used after instance is loaded from DB
            });
    
            static::creating(function (Model $model) {
                $model->incrementing = false; // this is used for new instances
    
                if (empty($model->{$model->getKeyName()})) { // if it's not empty, then we want to use a specific id
                    $model->{$model->getKeyName()} = (string)Uuid::uuid4();
                }
            });
        }
    
        public function initializeUuidForKey()
        {
            $this->keyType = 'string';
        }
    }
    

    Hope this helps.