Laravel 5.2: use una cadena como clave principal personalizada para que la tabla Eloquent se convierta en 0

82

Estoy tratando de usar el correo electrónico como clave principal de mi tabla, por lo que mi elocuente código es-

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

Y mi DB es así

ingrese la descripción de la imagen aquí

pero si hago esto

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

Estoy recibiendo esto

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

Entonces, el token de verificación / clave principal se convierte en 0.

Alguien puede ayudarme porfavor?

Abrar Jahin
fuente

Respuestas:

181

Esto se agregó a la documentación de actualización el 29 de diciembre de 2015 , por lo que si actualizó antes, probablemente se lo perdió.

Al obtener cualquier atributo del modelo, comprueba si esa columna debe convertirse en un número entero, cadena, etc.

De forma predeterminada, para las tablas de incremento automático, se supone que el ID es un número entero en este método:

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

Entonces la solución es:

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
fuente
3
¿Hay alguna razón por la que el $incrementingcampo sea público en lugar de protegido?
Mubashar Abbas
5
@MubasharAbbas Bueno, tu modelo tiene que coincidir con Eloquent. Ahora bien, ¿por qué Eloquent hace $incrementingpúblico y $primaryKeyprotege? Es bastante arbitrario. Supongo $incrementingque no tenían métodos getter o setter en versiones anteriores de Eloquent (ahora sí) y simplemente no querían hacer un cambio importante después de agregarlos
andrewtweber
1
Si no tiene clave principal (o claves compuestas, las cuales no son compatibles con elocuente), y que está tratando de repetir tales mesa con chunk, puede enfrentar el siguiente error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'example.' in 'order clause'. EN este caso, debe definir explícitamente la orderBydeclaración, que Eloquent está tratando de adjuntar a su consulta con la clave principal.
antongorodezkiy
Es triste que este sea el tipo de cosas que hace Laravel que me impiden amar con todo mi corazón. ¿No tendría más sentido detectar el tipo de columna (como ocurre con tantas otras columnas)?
Miss Amelia Sara
7

Hay dos propiedades en el modelo que necesita configurar. El primero $primaryKeyen decirle al modelo en qué columna esperar la clave principal. El segundo $incrementingpara que sepa que la clave principal no es un valor lineal de incremento automático.

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

    public $incrementing = false;
}

Para obtener más información, consulte la Primary Keyssección de la documentación sobre Eloquent .

Ave zancuda
fuente
1
Debe public $incrementingcoincidir con la clase principal.
andrewtweber
2

Estaba usando Postman para probar mi API de Laravel.

Recibí un error que decía

"SQLSTATE [42S22]: Columna no encontrada: 1054 Columna desconocida" porque Laravel estaba intentando crear automáticamente dos columnas "created_at" y "updated_at".

Tuve que ingresar public $timestamps = false;a mi modelo. Luego, volví a probar con Postman y vi que "id" = 0se estaba creando una variable en mi base de datos.

Finalmente tuve que agregar public $incrementing false;para arreglar mi API.

Erich Meissner
fuente
2

sigue usando la identificación


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

y recibe el correo electrónico:

$usr = User::find($id);
$token = $usr->verification_token;
$email = UserVerification::find($token);
Zμ 1
fuente