I'm trying to create foreign keys in Laravel. However, when I migrate my table using Artisan, I am thrown the following error.
Schema::create('billing_transactions', function (Blueprint $table) {
$table->id();
$table->integer('payment_amount')->default(0);
$table->tinyInteger('status')->default(0);
$table->foreignIdFor(PatientVisit::class)->nullable()->constrained()->onDelete('cascade')->onUpdate('cascade');
$table->foreignIdFor(BillingInvoice::class)->nullable()->constrained()->onDelete('cascade')->onUpdate('cascade');
$table->foreignId('created_by_id')->nullable()->constrained('users')->onDelete('cascade')->onUpdate('cascade');
$table->foreignId('updated_by_id')->nullable()->constrained('users')->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
(SQL: alter table billing_transactions add constraint
billing_transactions_billing_invoice_id_foreign foreign key
(billing_invoice_id) references billing_invoices (id) on delete
cascade on update cascade)
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->BigInteger('role_id')->unsigned();
$table->BigInteger('lang_id')->unsigned()->nullable();
$table->BigInteger('reference_id')->unsigned()->nullable()->default(null);
$table->string('name');
$table->string('surname');
$table->boolean('blocked')->default(0);
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::table('users', function($table) {
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->foreign('lang_id')->references('id')->on('languages')->onDelete('cascade');
$table->foreign('reference_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('users', function($table) {
$table->dropForeign(['role_id']);
$table->dropColumn('role_id');
$table->dropForeign(['lang_id']);
$table->dropColumn('lang_id');
$table->dropForeign(['reference_id']);
$table->dropColumn('reference_id');
$table->dropUnique(['email']);
$table->dropColumn('email');
});
Schema::dropIfExists('users');
}
I use like that. For foreigns and uniques.
Related
Error: SQLSTATE[HY000]: General error: 1005 Can't create table epicit_cms.ep_users (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table ep_users add constraint ep_users_client_id_foreign foreign key (client_id) references ep_clients (id) on delete cascade)
can someone explain what should do?
what i want to achieve is. if i want to delete a client it should delete users with the same client id too but i can't make it happen because i cant migrate my foreign key
Migration:
users table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->string('insertion')->nullable();
$table->string('secondname');
$table->string('email')->unique();
$table->string('password');
$table->integer('client_id');
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$table->boolean('admin')->default(0);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
Clients table
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('company_name');
$table->string('postal_code');
$table->string('street');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('clients');
}
Models:
User relation
public function Client()
{
return $this->belongsTo(Client::class );
}
Client relation
public function user()
{
return $this->hasMany(User::class);
}
change your migration like this
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->string('insertion')->nullable();
$table->string('secondname');
$table->string('email')->unique();
$table->string('password');
$table->foreignId('client_id')
->constrained()
->onDelete('cascade');
$table->boolean('admin')->default(0);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
You should make sure, your Clients table migration is running before users table migration.
And also your foreign_key field and your id should be of the same type, for example, if clients.id is bigIncrements, your foreign_key inside your user table also should be bigInteger.
Okay thank you guys for showing more then one way to do it. I fixed my code using this $table->foreignId('client_id')->constrained()->onDelete('cascade'); the way #sherifcoder did it and i changed client tabel from this $table->uuid('id')->primary(); to $table->id('id'); .I did more research into UUID and what it appears to be that UUID it doesn't always work with FKS. Again thank you for time
can someone tell me why do I get a foreign key is incorrectly formed?
Here is part of the code:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('title');
$table->text('content');
$table->string('featured');
$table->string('slug');
$table->foreignId('category_id')->constrained()->onDelete('cascade');
$table->softDeletes();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
Here is the categories table:
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
Note
It does not drop this error for 'user_id' foreign key just for categories.
FIX FOR THIS ISSUE
just change date on your database/migrations - migration for example if you want your categories to be created before posts table do this change:
2020_08_06_172006_create_posts_table.php
2020_08_09_172006_create_categories_table.php
change date on categories migration from
2020_08_09 to for example 2020_07_09
I'm guessing your table posts is created before categories
Therefore, you cannot constraint posts.category_id to the categories.id table.
In order to fix the issue you should create the table categories before creating the table posts
1.why cant I migrate ?
I wanted to crate role permission table, but i cant add foreign key, i got this error : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
i tried to migrate, but got some errors
i dont know what should i do in laravel 5.8
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRoleAndPermissionTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('title')->nullable();
$table->timestamps();
});
Schema::create('permissions', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('title')->nullable();
$table->timestamps();
});
**Schema::create('role_user', function (Blueprint $table) {
$table->integer('role_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade')->onUpdate('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$table->primary(['role_id','user_id']);
});
2.it just migrate upper tables,It wont migrate this table ?
Schema::create('permission_role', function (Blueprint $table) {
$table->integer('permission_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade')->onUpdate('cascade');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade')->onUpdate('cascade');
$table->primary(['permission_id','role_id']);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('role_and_permission');
}
}
Comment or remove all $table->foreign('') from all migration. It will work.
The best solution is to use $table->bigIncrements('') on primary key rather than $table->increments('') and $table->unsignedBigInteger(''); for foreign keys rather than $table->integer('');.
Because Laravel 5.8 uses $table->bigIncrements('') on primary key and $table->unsignedBigInteger(''); for foreign keys.
am trying to do laravel migration but am getting this error
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table `urbancruise`.`#sql-18f8_112` (errno: 150 "Foreign key cons
traint is incorrectly formed") (SQL: alter table `posts` add constraint `posts_category_id_foreign` foreign key (`c
ategory_id`) references `categories` (`id`))
here is my code
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
public function down(){
Schema::drop('categories');
}
public function up(){
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->bigInteger('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('categories');
$table->timestamps();
});
}
public function down(){
Schema::drop('posts');
}
When you are creating a foreign key, the categories.id and posts.category_id must have the same type.
Swap the ->bigInteger() with ->integer()should solve your problem:
Your categories migration:
public function up(){
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
public function down(){
Schema::drop('categories');
}
In your posts migration:
public function up(){
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id', false, true);
//Or $table->unsignedInteger('category_id');
$table->foreign('category_id')
->references('id')
->on('categories');
$table->timestamps();
});
}
public function down(){
Schema::drop('posts');
}
Hope it helps.
Foreign key should always be of same type in both child and parent table.
In your case, categories.id is of type ٰINTEGER while posts.category_id is defined as BIGINT. Replacing your posts migration with below should work.
public function up() {
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('categories');
$table->timestamps();
});
}
Im using the package https://github.com/musonza/groups to added group system on my laravel app, but when I want to migrate I get the error:
Migration table created successfully.
Migrating: 2019_05_26_125854_create_groups_tables
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1005 Can't create table `groupsystem`.`#sql-2678_26` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `groups` add constraint `groups_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)
This is my 2 migrations table code:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
And also this is the migration table I get from installing the package:
That I mentioned in the link in the top of this post
This is the first time I try to use this package
And im trying tocreate a group system on my laravel application
Any other suggetions will be welcomed
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGroupsTables extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('groups', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('description')->nullable();
$table->string('short_description')->nullable();
$table->string('image')->nullable();
$table->string('url')->nullable();
$table->integer('user_id')->unsigned();
$table->boolean('private')->unsigned()->default(false);
$table->integer('conversation_id')->unsigned()->nullable();
$table->text('extra_info')->nullable();
$table->text('settings')->nullable();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
Schema::create('group_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('group_id')->unsigned();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('group_id')
->references('id')
->on('groups')
->onDelete('cascade');
});
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('body');
$table->string('type');
$table->integer('user_id')->unsigned();
$table->text('extra_info')->nullable();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->string('body');
$table->integer('user_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->string('type')->nullable();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users');
$table->foreign('post_id')
->references('id')
->on('posts');
});
Schema::create('group_post', function (Blueprint $table) {
$table->integer('group_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->timestamps();
$table->foreign('group_id')
->references('id')
->on('groups')
->onDelete('cascade');
$table->foreign('post_id')
->references('id')
->on('posts')
->onDelete('cascade');
});
Schema::create('likes', function (Blueprint $table) {
$table->integer('user_id')->index();
$table->integer('likeable_id')->unsigned();
$table->string('likeable_type');
$table->primary(['user_id', 'likeable_id', 'likeable_type']);
$table->timestamps();
});
Schema::create('reports', function (Blueprint $table) {
$table->integer('user_id')->index();
$table->integer('reportable_id')->unsigned();
$table->string('reportable_type');
$table->primary(['user_id', 'reportable_id', 'reportable_type']);
$table->timestamps();
});
Schema::create('group_request', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->integer('group_id')->unsigned()->index();
$table->timestamps();
$table->foreign('group_id')
->references('id')
->on('groups')
->onDelete('cascade');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('groups');
Schema::drop('group_user');
Schema::drop('posts');
Schema::drop('comments');
Schema::drop('group_post');
Schema::drop('likes');
Schema::drop('reports');
Schema::drop('group_request');
}
}
If you have used laravel 5.8 then
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
If you have used laravel < 5.8 then
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
I did found the solution it's because of the new Laravel 5.8.3 it comes with unsignedBigInteger(id) instead of increments(id)