34

My foreign key relates to its own table. This was to produce posts with hierarchy.

Now when I try and drop the column in the database, it gives me this error:

1553 - Cannot drop index 'post_field_properties_parent_id_index': needed in a foreign key constraint

This is the code:

public function down()
{
        Schema::table( "post_field_properties", function( $table )
        {
            $table->dropForeign('parent_id');
            $table->dropColumn('parent_id');
        } );
}

The only way I seem to be able to do it, is to goto phpmyadmin and remove the foreign key itself. and then drop the column.

John Y
  • 14,123
  • 2
  • 48
  • 72
Jimmyt1988
  • 20,466
  • 41
  • 133
  • 233
  • What are the table names that you have connected through the foreign key? – Nick Law Oct 29 '14 at 10:44
  • 2
    Is "parent_id" really the name of the foreign key? Normally it's something like shown [here](http://laravel.com/docs/4.2/schema#foreign-keys) – lukasgeiter Oct 29 '14 at 10:49

7 Answers7

51

Just figured this out for my own project. When you are dropping a foreign key, you need to concatenate the table name and the columns in the constraint then suffix the name with "_foreign"

http://laravel.com/docs/5.1/migrations#foreign-key-constraints

public function down()
{
        Schema::table( "post_field_properties", function( $table )
        {
            $table->dropForeign('post_field_properties_parent_id_foreign');
            $table->dropColumn('parent_id');
        });
}
atm
  • 1,684
  • 1
  • 22
  • 24
  • 4
    Optionally you may specify the column name of the foreign key to drop by passing an array to the dropForeign method: `$table->dropForeign(['parent_id']);` It is very important to drop the foreign key before dropping the related column. – Andrea Marco Sartori May 24 '17 at 10:35
  • 2
    Can also confirm this works in Laravel 5.4.30. This answer solved some big headaches for me :). – Rob Jul 22 '17 at 14:13
16

Here’s how to do it:

  1. Log in to your database and lookup the name of the foreign key relationship. If you use phpmyadmin, go to the table, click the “Structure” tab, click the link “Relation View”

Important Note: to see “Relation View” make sure your tables “Storage Engine” is InnoDB if not review this Q&A

and wait a few seconds for it to load. Search for the field “Constraint name”. In my example this is: “contribution_copyright_id_foreign”

  1. Go to the Laravel migration script (or create one). The trick is to first drop the foreign key relationship and then drop the column.

    public function down()

    {

         Schema::table('contribution', function(Blueprint $table){
    
             $table->dropForeign('contribution_copyright_id_foreign');
    
             $table->dropColumn('copyright_id');
    
         });
    

If you want to remove a table where a foreign key is present, you also first have to drop the foreign key relationship.

copied from here

Hope it help someone

Yousef Altaf
  • 2,631
  • 4
  • 46
  • 71
4

I'm using Laravel 8, and turns out there's dropConstrainedForeignId that we can use for this. So instead of this one provided in another answer:

Schema::table( "post_field_properties", function( $table )
{
    $table->dropForeign('post_field_properties_parent_id_foreign');
    $table->dropColumn('parent_id');
});

You can write:

Schema::table( "post_field_properties", function( $table )
{
    $table->dropConstrainedForeignId('parent_id');
});
rifqy abdl
  • 156
  • 1
  • 8
3

You may pass an array value which will automatically use the conventional constraint name when dropping: http://laravel.com/docs/5.1/migrations#foreign-key-constraints

 Schema::table('contribution', function(Blueprint $table){
     $table->dropForeign(['copyright_id']);
     $table->dropColumn('copyright_id');
 });
2

You may pass an array of foreign keys inside the dropForeign() function, so Laravel will automatically concatenate the table name at the begining of the key name and 'foreign' at the end of it.

So please, try something like this code bellow in your down() function.

 Schema::table('contribution', function(Blueprint $table){
     $table->dropForeign(['copyright_id']);
     $table->dropColumn('copyright_id');
 });
Rafael Xavier
  • 956
  • 13
  • 13
  • Explaining why this answer improves on the existing answers would make it more valuable. Is this a new feature that wasn't available 7 years ago? Is there documentation you can link to? You should also tailor your answer to match the identifiers in the question. (Also, starting your answer with "Please try" makes it sound like a guess, not an answer.) – miken32 Dec 28 '21 at 19:43
1

To check the name of the foreign key , first backup your database to .sql

there you will see the name of your foreign key like this :

...
KEY `employees_parent_id_foreign` (`parent_id`),
CONSTRAINT `employees_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `laravel_article` (`id`) ON DELETE CASCADE
...

in my case is laravel 5.4, it start by this format : tablename_columnname_foreign

so in your laravel (here i try to drop foreign key from employee table)

Schema::table("employees", function( $table )
{
    $table->dropForeign('employees_parent_id_foreign');
    $table->dropColumn('parent_id');
});
Anthony Kal
  • 2,729
  • 1
  • 20
  • 18
0

Try placing "_foreign" on the end of the column name. For example:

public function down()
{
        Schema::table( "post_field_properties", function( $table )
        {
            $table->dropForeign('parent_id_foreign');
            $table->dropColumn('parent_id');
        });
}
Nick Law
  • 1,580
  • 3
  • 17
  • 27