devSSI's avatar

getKeyName in Laravel 10 causes issue in test when slug is primary key

I have been working on rest api and now I am working on some tests, but since I want to use slug on my model as primary key (usual setup with getKeyName) I have strange behaviour. For example for this create method:

$modelInstance = Model::create([
            'title' => 'Old Title',
            'slug' => Str::slug('Old Title'),
            'description' => 'Old description',
            'rating' => 4.2,
        ]);

I get these results when dump test:

    ]
  #original: array:6 [
    "title" => "Old Title"
    "slug" => 9
    "description" => "Old description"
    "rating" => 4.2
    "updated_at" => "2023-11-17 08:45:08"
    "created_at" => "2023-11-17 08:45:08"
  ]
  #changes: []
  #casts: []
  #classCastCache: []
  #attributeCastCache: []

Then when I comment this:

    public function getKeyName(): string
    {
        return 'slug';
    }

part in my model and run the same test I get this:

  ]
  #original: array:7 [
    "title" => "Old Title"
    "slug" => "old-title"
    "description" => "Old description"
    "rating" => 4.2
    "updated_at" => "2023-11-17 08:47:31"
    "created_at" => "2023-11-17 08:47:31"
    "id" => 9
  ]
  #changes: []

I haven't worked much with Laravel 10 lately, but is there something I am missing and I should be aware of?

0 likes
5 replies
krisi_gjika's avatar

have you set auto incrementing to false in your model? I think your model is trying to apply the next id to itself thinking the key is auto incrementing.

1 like
devSSI's avatar

@krisi_gjika You are partially right :D I forgot to post the code that worked for me. This is solved issue :)

devSSI's avatar
devSSI
OP
Best Answer
Level 5

Issue is solved by adding this part to the model:

    public function getKeyName(): string
    {
        return 'slug';
    }

    protected $casts = ['slug' => 'string'];
    protected $primaryKey = 'slug';
    protected $keyType = 'string';
    public $incrementing = false;
ihorshto's avatar

Hello, getKeyName() is just the method that returns $primaryKey, so you can simplify it

Please or to participate in this conversation.