This is an attempt to learn Laravel (specifically v5.x) by porting an old project using a SQL dump that contains this:
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`locationid` int(11) NOT NULL,
`username` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`email` varchar(200) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`firstname` varchar(100) NOT NULL,
`lastname` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
`active` bit(1) DEFAULT b'1',
`token` varchar(100) DEFAULT NULL,
`token_created` timestamp NULL DEFAULT NULL,
`role` varchar(45) NOT NULL DEFAULT 'user',
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `email_UNIQUE` (`email`),
UNIQUE KEY `username_UNIQUE` (`username`),
KEY `location_idx` (`locationid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
And at the bottom of the dump had this related to this specific table:
ALTER TABLE `user`
ADD CONSTRAINT `location_userfk` FOREIGN KEY (`locationid`) REFERENCES `location` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
From a couple stackoverflow questions 1, 2, 3; I've altered my original code to split out the foreign key to Schema::table from Schema::create and added unsigned() to each of the fields:
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->integer('locationid')->unsigned();
// $table->foreign('locationid')->references('id')->on('location');
$table->string('username', 60)->unique();
$table->string('email', 200)->unique();
$table->string('firstname', 100);
$table->string('lastname', 100);
$table->string('password', 255);
$table->boolean('active')->default(TRUE);
$table->string('role', 45)->default('user');
// $table->string('token', 255)->nullable()->default(NULL);
// $table->string('token_create')->nullable()->default(NULL);
$table->rememberToken();
$table->timestamps();
});
Schema::table('users', function(Blueprint $table)
{
$table->foreign('locationid')->references('id')->on('location');
});
}
But I still get an error when I migrate when using an empty newly created DB:
exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint' in /home/vagrant/projects/communityfuturesbc/vendor/laravel/framework/src/Illuminate/Database/Connection.php:358
Stack trace:
#0 /home/vagrant/projects/communityfuturesbc/vendor/laravel/framework/src/Illuminate/Database/Connection.php(358): PDOStatement->execute(Array) etc...
Next exception 'Illuminate\Database\QueryException' with message 'SQLSTATE[HY000]: General err
or: 1215 Cannot add foreign key constraint (SQL: alter table `users` add constraint users_loca
tionid_foreign foreign key (`locationid`) references `location` (`id`))' in /home/vagrant/proj
ects/communityfuturesbc/vendor/laravel/framework/src/Illuminate/Database/Connection.php:614
Stack trace:
#0 /home/vagrant/projects/communityfuturesbc/vendor/laravel/framework/src/Illuminate/Database/Connection.php(570): Illuminate\Database\Connection->runQueryCallback('alter table `us...', Ar
ray, Object(Closure))
Which according to MySQL means:
Error: 1215 SQLSTATE: HY000 (ER_CANNOT_ADD_FOREIGN)
Message: Cannot add foreign key constraint
After which I can't rollback or migrate again without getting another type of error regarding the existence of users table already in the DB so each time I try a version of the above code I've been dropping my DB each time.
I'm sure after fixing this it will occur in all the other tables, which are similar or have more than one foreign key so hopefully whatever fixes this will work for the rest.
Make sure your location table exists first. Referencing a non existing table can cause the error you're having.
You have to change the migrations order
Should be:
Finally:
I had the same problem, what did I do?
simple... in your
create_users
migration file try this....:)
The error is caused by the migration which tries to reference on an non existing column. To prevent this issue create referenced column before performing the foreign key creation.
To create table structures with dependencies you can either create the migration files in the correct order, or put all migrations into one big file or at least create all tables without foreign keys and create another file which performs the key-creation in the end. Keep in min this is only necessary if you want to rescript an existing data structure or want to fix the migration order. Otherwise use the
php artisan make:migration
command.Well, its little confusing part here, first create an table('users') when up method run and then respectively update table('users') by adding in Foreign key in the same table. I think its can not perform at the same time add and update using migration. For the solution of your code would be:
Now, you creating your foreign by creating your table. so its should work if not let me know.