Laravel 5.2 - Використання рядка як користувацького первинного ключа для красномовної таблиці стає 0


84

Я намагаюся використовувати електронну пошту як основний ключ моєї таблиці, тому мій красномовний код -

<?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';
}

І моя БД така -

введіть тут опис зображення

але якщо я це зроблю-

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

Я отримую це-

{
  "email": "sdfsdf@sdfsdf.sdf",
  "verification_token": 0,
  "created_at": "2016-01-03 22:27:44",
  "updated_at": "2016-01-03 22:27:44"
}

Отже, маркер підтвердження / первинний ключ стає 0.

Хто-небудь може допомогти?

Відповіді:


184

Це було додано до документації з оновлення 29 грудня 2015 року , тому, якщо ви проводили оновлення раніше, то, можливо, пропустили.

При виборі будь-якого атрибута з моделі він перевіряє, чи слід використовувати цей стовпець як ціле число, рядок тощо.

За замовчуванням для таблиць з автоматичним збільшенням ідентифікатор вважається цілим числом у цьому методі:

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

Тож рішення:

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';
}

3
Чи є причина, чому $incrementingполе є загальнодоступним, а не захищеним?
— Мубашар Аббас,

5
@MubasharAbbas Ну, ваша модель повинна відповідати красномовству. Тепер, чому Eloquent $incrementingоприлюднює та $primaryKeyзахищає? Це досить довільно. Я здогадуюсь, що $incrementingв попередніх версіях Eloquent не було методів getter або setter (зараз це відбувається), і вони просто не хотіли вносити
— важкі

1
Якщо у вас немає первинного ключа (або складові ключі, які не підтримуються красномовні), і ви намагаєтеся ітерацію таку таблицю chunk, ви можете зіткнутися наступне повідомлення про помилку: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'example.' in 'order clause'. У цьому випадку вам потрібно чітко визначити orderByоператор, який Eloquent намагається долучити до вашого запиту за допомогою первинного ключа.
— antongorodezkiy

Сумно, що саме такі речі робить Ларавель, що заважає мені любити всім серцем. Хіба не виявлення типу стовпця (як це робиться з такою кількістю інших стовпців) має більше сенсу?
— Міс Амелія Сара


7

Є дві властивості моделі, яку потрібно встановити. Перший, $primaryKeyхто повідомив моделі, в якому стовпці очікувати первинний ключ. Другий, $incrementingщоб він знав, що первинний ключ не є лінійним значенням автоматичного збільшення.

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

    public $incrementing = false;
}

Для отримання додаткової інформації дивіться Primary Keysрозділ у документації на Eloquent .


1
Це має public $incrementingвідповідати батьківському класу.
— andrewtweber

2

Я використовував Поштовика для тестування свого API Laravel.

Я отримав повідомлення про помилку

"SQLSTATE [42S22]: Стовпець не знайдено: 1054 Невідомий стовпець", оскільки Laravel намагався автоматично створити два стовпці "created_at" і "updated_at".

Мені довелося увійти public $timestamps = false;до своєї моделі. Потім я ще раз протестував у Postman і побачив, що "id" = 0в моїй базі даних створюється змінна.

Нарешті мені довелося додати, public $incrementing false;щоб виправити свій API.


2

продовжуйте використовувати ідентифікатор


<?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';
}

та отримати електронне повідомлення:

$usr = User::find($id);
$token = $usr->verification_token;
$email = UserVerification::find($token);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.