mariadb - relacionales - mostrar campo(nombre) de otra tabla por medio de la llave foránea laravel
La restricción de la clave foránea de la migración de Laravel se forma incorrectamente (13)
Al migrar mi base de datos, aparece este error, a continuación se muestra mi código seguido del error que recibo al intentar ejecutar la migración.
Código
public function up()
{
Schema::create(''meals'', function (Blueprint $table) {
$table->increments(''id'');
$table->integer(''user_id'')->unsigned();
$table->integer(''category_id'')->unsigned();
$table->string(''title'');
$table->string(''body'');
$table->string(''meal_av'');
$table->timestamps();
$table->foreign(''user_id'')
->references(''id'')
->on(''users'')
->onDelete(''cascade'');
$table->foreign(''category_id'')
->references(''id'')
->on(''categories'')
->onDelete(''cascade'');
});
}
Mensaje de error
[Illuminate/Database/QueryException]
SQLSTATE[HY000]: General error: 1005 Can''t create table `meal`.`#sql-11d2_1
4` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter
table `meals` add constraint meals_category_id_foreign foreign key (`catego
ry_id`) references `categories` (`id`) on delete cascade)
@JuanBonnett Su pregunta me inspiró en la respuesta, adopté en laravel para automatizar el proceso sin tener en cuenta el tiempo de creación del archivo. De acuerdo con el flujo de trabajo, las comidas se crearán antes de la tabla (categorías) porque he creado un archivo de esquema (comidas) Antes de las categorías. eso fue mi culpa
Agregue -> nullable () en su campo y asegúrese de que realmente existan todos los campos a los que se refiere.
Al crear una nueva tabla en Laravel. Se generará una migración como:
$table->bigIncrements(''id'');
En lugar de (en versiones anteriores de Laravel):
$table->increments(''id'');
Cuando se usa bigIncrements
la clave externa espera un bigInteger en lugar de un entero . Entonces tu código se verá así:
public function up()
{
Schema::create(''meals'', function (Blueprint $table) {
$table->increments(''id'');
$table->unsignedBigInteger(''user_id''); //changed this line
$table->unsignedBigInteger(''category_id''); //changed this line
$table->string(''title'');
$table->string(''body'');
$table->string(''meal_av'');
$table->timestamps();
$table->foreign(''user_id'')
->references(''id'')
->on(''users'')
->onDelete(''cascade'');
$table->foreign(''category_id'')
->references(''id'')
->on(''categories'')
->onDelete(''cascade'');
});
}
También puedes usar increments
lugar de bigIncrements
como dijo Kiko Sejio .
La diferencia entre Integer y BigInteger es el tamaño:
- int => 32 bits
- bigint => 64 bits
El orden de creación de los archivos de migración debe ordenarse y la clave externa debe tener una propiedad exactamente similar a la clave principal en la otra tabla.
En mi caso, el problema era que una de las tablas a las que se hacía referencia era InnoDB y la otra era MyISAM .
MyISAM no tiene soporte para relaciones de clave externa.
Entonces, ahora ambas tablas son InnoDB . Problema resuelto.
En mi caso, la nueva convención de laravel estaba causando este error.
Solo con un simple intercambio de la creación de tablas, el id
hizo el truco.
$table->increments(''id''); // ok
, en lugar de:
$table->bigIncrements(''id''); // was the error.
Ya trabajando con Laravel v5.8
, nunca antes había tenido este error.
Las migraciones deben ser creadas de arriba a abajo.
Primero crea las migraciones para las tablas que no pertenecen a nadie.
A continuación, cree las migraciones para las tablas que pertenecen a la anterior.
Respuesta simplificada al problema del motor de mesa:
Para configurar el motor de almacenamiento para una tabla, configure la propiedad del motor en el generador de esquemas:
Schema::create(''users'', function ($table) {
$table->engine = ''InnoDB'';
$table->increments(''id'');
});
De Laravel Docs: https://laravel.com/docs/5.2/migrations
Para mí todo estaba en el orden correcto, pero aún así no funcionó. Luego descubrí, sin darme cuenta, que la clave principal debía estar sin firmar.
//this didn''t work
$table->integer(''id'')->unique();
$table->primary(''id'');
//this worked
$table->integer(''id'')->unsigned()->unique();
$table->primary(''id'');
//this worked
$table->increments(''id'');
Recuerde que esto es importante: los campos referenciados y de referencia deben tener exactamente el mismo tipo de datos.
Si está utilizando ->onDelete(''set null'')
en su definición de clave externa, asegúrese de que el campo de la clave externa sea nullable()
es decir
//Column definition
$table->integer(''user_id'')->unsigned()->index()->nullable(); //index() is optional
//...
//...
//Foreign key
$table->foreign(''user_id'')
->references(''id'')
->on(''users'')
->onDelete(''set null'');
Tal vez pueda ser de ayuda para cualquiera que aterrice aquí: acabo de experimentar este mismo problema, y en mi caso fue que tenía una restricción única (compuesta) establecida en la columna de clave externa ANTES de la restricción de clave externa. Resolví el problema al tener la declaración "única" colocada DESPUÉS de la declaración "extranjera".
Trabajos:
$table->foreign(''step_id'')->references(''id'')->on(''steps'')->onDelete(''cascade'');
$table->unique([''step_id'',''lang'']);
No funciona
$table->unique([''step_id'',''lang'']);
$table->foreign(''step_id'')->references(''id'')->on(''steps'')->onDelete(''cascade'');
simplemente agregue ->unsigned()->index()
al final de la clave foránea y funcionará
Debería crear su migración en orden, por ejemplo, quiero que mis users
tengan un campo role_id
que sea de mi tabla de roles
La primera vez que comienzo a hacer mi migración de roles es php artisan make:migration create_roles_table --create=roles
luego mi segunda migración de usuario, php artisan make:migration create_users_table --create=users
php artisan migration
se ejecutará utilizando el orden de los archivos creados 2017_08_22_074128 _create_roles_table.php y 2017_08_22_134306 _create_users_table, compruebe el orden de fecha y hora, que será el orden de ejecución.
archivos 2017_08_22_074128_create_roles_table.php
public function up()
{
Schema::create(''roles'', function (Blueprint $table) {
$table->increments(''id'');
$table->string(''name'', 50);
$table->timestamps();
});
}
2017_08_22_134306_create_users_table
public function up()
{
Schema::create(''users'', function (Blueprint $table) {
$table->increments(''id'');
$table->integer(''role_id'')->unsigned();
$table->string(''name'');
$table->string(''phone'', 20)->unique();
$table->string(''password'');
$table->rememberToken();
$table->boolean(''active'');
$table->timestamps();
$table->foreign(''role_id'')->references(''id'')->on(''roles'');
});
}