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.