Laravel 5.2 - Użyj ciągu jako niestandardowego klucza podstawowego dla tabeli elokwentnej wynosi 0

84

Próbuję użyć poczty e-mail jako klucza podstawowego mojej tabeli, więc mój wymowny kod to-

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class UserVerification extends Model
{
    protected $table = 'user_verification';
    protected $fillable =   [
                                'email',
                                'verification_token'
                            ];
    //$timestamps = false;
    protected $primaryKey = 'verification_token';
}

A moja DB jest taka-

wprowadź opis obrazu tutaj

ale jeśli to zrobię-

UserVerification::where('verification_token', $token)->first();

Rozumiem to-

{
  "email": "[email protected]",
  "verification_token": 0,
  "created_at": "2016-01-03 22:27:44",
  "updated_at": "2016-01-03 22:27:44"
}

Tak więc token weryfikacyjny / klucz podstawowy przyjmuje wartość 0.

Czy ktoś może pomóc?

Abrar Jahin
źródło

Odpowiedzi:

184

Zostało to dodane do dokumentacji aktualizacji 29 grudnia 2015 r. , Więc jeśli aktualizowałeś wcześniej, prawdopodobnie to przegapiłeś.

Podczas pobierania dowolnego atrybutu z modelu sprawdza, czy ta kolumna powinna być rzutowana jako liczba całkowita, łańcuch itp.

Domyślnie w przypadku tabel z automatycznym zwiększaniem wartości identyfikator jest liczbą całkowitą w tej metodzie:

https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L2790

Tak więc rozwiązaniem jest:

class UserVerification extends Model
{
    protected $primaryKey = 'your_key_name'; // or null

    public $incrementing = false;

    // In Laravel 6.0+ make sure to also set $keyType
    protected $keyType = 'string';
}
andrewtweber
źródło
3
Is there a reason why $incrementing field is public instead of protected?
Mubashar Abbas
5
@MubasharAbbas Well your model has to match Eloquent. Now, why does Eloquent make $incrementing public and $primaryKey protected? It's pretty arbitrary. I'm guessing $incrementing did not have getter or setter methods in earlier versions of Eloquent (it now does) and they just didn't want to make a breaking change after adding them in
andrewtweber
1
If you have no primary key (or composite keys, which are not supported by Eloquent), and you're trying to iterate such table with chunk, you can face the following error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'example.' in 'order clause'. IN this case you need to explicitly define orderBy statement, which Eloquent is trying to attach to your query with the primary key.
antongorodezkiy
Sad that these are the types of things Laravel does that prevents me from loving with all my heart. Wouldn't detecting the column type (like it does with so many other columns) make more sense?
Miss Amelia Sara
7

Theres two properties on the model you need to set. The first $primaryKey to tell the model what column to expect the primary key on. The second $incrementing so it knows the primary key isn't a linear auto incrementing value.

class MyModel extends Model
{
    protected $primaryKey = 'my_column';

    public $incrementing = false;
}

For more info see the Primary Keys section in the documentation on Eloquent.

Wader
źródło
1
It needs to be public $incrementing to match the parent class.
andrewtweber
2

I was using Postman to test my Laravel API.

I received an error that stated

"SQLSTATE[42S22]: Column not found: 1054 Unknown column" because Laravel was trying to automatically create two columns "created_at" and "updated_at".

I had to enter public $timestamps = false; to my model. Then, I tested again with Postman and saw that an "id" = 0 variable was being created in my database.

I finally had to add public $incrementing false; to fix my API.

Erich Meissner
źródło
2

keep using the id


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class UserVerification extends Model
{
    protected $table = 'user_verification';
    protected $fillable =   [
                            'id',
                            'email',
                            'verification_token'
                            ];
    //$timestamps = false;
    protected $primaryKey = 'verification_token';
}

and get the email :

$usr = User::find($id);
$token = $usr->verification_token;
$email = UserVerification::find($token);
Zμ 1
źródło