Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

General error: 1215 Cannot add foreign key constraint

Bom dia! Estou com problemas ao fazer a migration da primeira aula. Estou usando MySQL.

Sempre me retorna esse erro

  Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key con
straint (SQL: alter table `temporadas` add constraint `temporadas_serie_id_foreign` foreign key (`serie_
id`) references `series` (`id`))

Quando verifico no banco, a tabela está criada, porém, sem o relacionamento.

Fiz o seguinte teste: Excluí a tabela 'temporadas' do banco e alterei o código da migration adicionando o valor unsigned para o serie_id

 public function up()
    {
        Schema::create('temporadas', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('numero');
            $table->integer('serie_id')->unsigned();

            $table->foreign('serie_id')
                ->references('id')
                ->on('series');
        });
    }

Desta forma funciona certinho a criação da tabela de temporadas. Porém, o mesmo erro se repete na hora de criar a tabela de episodios.

 Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `episodios` add constraint `episodios_temporada_id_foreign` foreign key (`temporada_id`) references `temporadas` (`id`))

Segui o mesmo passo anterior adicionando o atributo unsigned para o 'temporada_id', mas não funcionou como na tabela de temporadas.

 public function up()
    {
        Schema::create('episodios', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('numero');
            $table->integer('temporada_id')->unsigned();

            $table->foreign('temporada_id')
                ->references('id')
                ->on('temporadas');
        });
    }

A tabela episodios é criada, porém sem o relacionamento. Já tentei remover o banco e executar a migration novamente, mas, sempre para nesse ponto.

Tentei também o comando migrate:refresh mas não obtive sucesso.

Alguém consegue me ajudar e me explicar o que está acontecendo por favor? Desde-já obrigado.

1 resposta
solução!

Descobri o problema.

Quando criamos a tabela de séries na primeira parte do curso, o campo de ID da série foi atribuído como increments()

    public function up()
    {
        Schema::create('series', function (Blueprint $table) {
           $table->increments('id');
            $table->string('nome');
        });
    }

Desta forma, no banco de dados ele foi criado como INT e Unsigned (mesmo sem passar o unsigned())

Já na criação das novas migrations temporadas por exemplo, o código gerado pelo artisan já vem a chave primária como bigIncrements() o que gera no banco de dados um BigINT e também Unsigned.

public function up()
{
    Schema::create('temporadas', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->integer('numero');
        $table->integer('serie_id');

        $table->foreign('serie_id')
            ->references('id')
            ->on('series');
    });
}

Como o campo id de séries é Unsigned, o serie_id também deve ser Unsigned. Aí a primeira parte está resolvida.

É só adicionar o unsigned()

public function up()
    {
        Schema::create('temporadas', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('numero');
            $table->integer('serie_id')->unsigned();

            $table->foreign('serie_id')
                ->references('id')
                ->on('series');
        });
    }

Já no caso da tabela de episódios temos que observar também que os campos devem ser iguais para fazermos o relacionamento.

serie_id em episodios e o id em na tabela temporada devem ser do mesmo tipo, e no código criamos o serie_id como INT e não BigINT Unsigned.

public function up()
{
    Schema::create('episodios', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->integer('numero');
        $table->integer('temporada_id');

        $table->foreign('temporada_id')
            ->references('id')
            ->on('temporadas');
    });
}

Desta forma, a solução seria alterar as migrations para ficarem todas com a mesma tipagem, BigInteger ou Integer:

No meu caso, coloquei todas como Integer

Temporada

public function up()
    {
        Schema::create('temporadas', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('numero');
            $table->integer('serie_id')->unsigned();

            $table->foreign('serie_id')
                ->references('id')
                ->on('series');
        });
    }

Episódios

public function up()
    {
        Schema::create('episodios', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('numero');
            $table->integer('temporada_id')->unsigned();

            $table->foreign('temporada_id')
                ->references('id')
                ->on('temporadas');
        });
    }

Caso alguém caia no mesmo problema está aí uma solução.