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.