I'm doing migrations for the DB of the enterprise I work for.
The issue is that the same table has 4 primary keys but this error is being throw by Laravel.
This is how my migrations look like:
Schema::create('ventas', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('empresa_id')->primary();
$table->integer('moneda_id')->primary();
$table->integer('user_id')->primary();
$table->foreign('empresa_id')->references('id')->on('empresas')->onDelete('restrict');
$table->foreign('moneda_id')->references('id')->on('monedas')->onDelete('restrict');
How can I solve this?
Thanks!
try this
public function up()
{
Schema::create('ventas', function (Blueprint $table) {
$table->id();
$table->foreignId('empresa_id')->nullable()->constrained()->onDelete('restrict');
$table->foreignId('moneda_id')->nullable()->constrained()->onDelete('restrict');
$table->foreignId('user_id')->nullable()->constrained()->onDelete('restrict');
$table->timestamps();
});
}
Related
I'm using my migrations in Laravel to create the relationships between tables, and I have 4 tables: users, members, member_skills, and skills. I have the following code for the users table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
$table->boolean('admin');
});
}
the members table:
public function up()
{
Schema::create('members', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('name');
$table->string('status');
$table->date('date')->nullable();
$table->text('project')->nullable();
$table->date('start')->nullable();
$table->foreign('name')->references('name')->on('users');
});
}
the member_skills table:
public function up()
{
Schema::create('member_skills', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('name');
$table->string('skill');
$table->foreign('name')->references('name')->on('members');
});
}
and the skills table:
public function up()
{
Schema::create('skills', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('skill');
$table->text('description');
$table->foreign('skill')->references('skill')->on('member_skills');
});
}
However, running my migrations results to (errno: 150 "Foreign key constraint is incorrectly formed"). I have read that changing the migration order should fix the problem, so I have arranged the 4 tables to be migrated in the order of users, members, member_skills, and skills, but I am still receiving the same error. Is there anything else I'm doing wrong?
Here is the right way todo this
public function up()
{
Schema::create('members', function (Blueprint $table) {
...
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
}
public function up()
{
Schema::create('member_skills', function (Blueprint $table) {
...
$table->unsignedBigInteger('member_id');
$table->foreign('member_id')->references('id')->on('members');
});
}
public function up()
{
Schema::create('skills', function (Blueprint $table) {
...
$table->unsignedBigInteger('member_skill_id');
$table->foreign('member_skill_id')->references('id')->on('member_skills');
});
}
more:https://laravel.com/docs/8.x/migrations#foreign-key-constraints
You should try using the id of the member table as the foreign key rather than the name in the member_skills schema
public function up()
{
Schema::create('member_skills', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('member_id');
$table->string('skill');
$table->foreign('member_id')->references('id')->on('members');
});
}
You are getting this error because you are trying to reference name in the member table which is already a foreign key to the users table.
You can access the name of the member through the id foreign key in your blade.
this is the migration
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->timestamps();
i have tried to do it with this lines
$table->bigInteger(‘user_id’)->unsigned()->nullable()->default(null);
$table->foreign(‘user_id’)->references(‘id’)->on(‘users’)->onDelete(‘cascade’);
what i did
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->integer(‘user_id’)->unsigned()->nullable()->default(null);
$table->foreign(‘user_id’)->references(‘id’)->on(‘users’)-
>onDelete(‘cascade’);
what i get
ErrorExceptionenter
Use of undefined constant ‘user_id’ - assumed '‘user_id’' (this will throw an Error in a future version of PHP)
#Mirage Three questions:
why are you using backticks instead of single quotes?
why are you using just $table->id(); when it should be $table->integer('id');?
why are you using $table->timestamps(); when it should be $table->timestamp('created');?
This migration with tweaks to be single quotes instead of backticks, correctly using $table->id(); and $table->timestamp('created'); works just fine for me:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Posts extends Migration
{
public function up()
{
if(!Schema::hasTable('posts')) {
Schema::connection('migrate')->create('testPosts', function (Blueprint $table) {
$table->integer('id');
$table->integer('user_id')->unsigned()->nullable()->default(null);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamp('created');
});
}
}
public function down()
{
if(Schema::hasTable('posts')) {
Schema::connection('migrate')->dropIfExists('posts');
}
}
}
I'm trying to work with foreign keys on Laravel. It's quite simple how to add foreign key on table. But if table can contain more than one foreign key, for example:
There is tables:
Building
id
name
companies(can be more than one)
and other table is:
Companies
id
name
As I remember from good practices, I should create other table like building_company with columns
building_id
company_id
If it's in good way, how Model of this 3rd table should be named and used, or maybe in Laravel there is other solutions for multiple FKs?
Thank you
Building table
public function up()
{
Schema::create('Building', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('companies');
$table->timestamps();
});
}
Companies table
public function up()
{
Schema::create('Companies', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
building_company table
public function up()
{
Schema::create('building_company', function (Blueprint $table) {
$table->increments('id');
$table->integer('building_id')->references('id')->on('Building')->onDelete('cascade');
$table->integer('company_id')->references('id')->on('Companies')->onDelete('cascade');
$table->timestamps();
});
}
Establish n:n relationship
Schema::create('building_companies', function (Blueprint $table) {
$table->integer('company_id')->unsigned();
$table->integer('building_id')->unsigned();
$table->foreign('building_id')
->references('id')
->on('building')
->onDelete('cascade');
$table->foreign('company_id')
->references('id')
->on('companies')
->onDelete('cascade');
});
You dont use a Model::class for a pivot table in Laravel because it doesn't support composite primary key,
You can declare a Pivot::class (Illuminate\Database\Eloquent\Relations\Pivot)
But most of the times (especially if there is only the ids) you dont declare the pivot class, You use ManyToMany (belongsToMany()) relation between the two main models (Building & Company in your case)
I know this question has been ask a lot of time but i tried every solutions and it still give me an error.
I want to migrate my tables :
class CreateFichesTable extends Migration
{
public function up()
{
Schema::create('fiches', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('type');
$table->string('nom');
$table->string('description');
$table->string('image');
$table->integer('equipe_id')->unsigned();
$table->timestamps();
});
Schema::table('fiches', function(Blueprint $table)
{
$table->foreign('equipe_id')->references('id')->on('equipes');
});
}
}
And
class CreateEquipesTable extends Migration
{
public function up()
{
Schema::create('equipes', function (Blueprint $table) {;
$table->increments('id');
$table->string('nom');
$table->string('image');
$table->timestamps();
});
}
}
And I get :
Exception trace:
1 PDOException::("SQLSTATE[HY000]: General error: 1215 Cannot add foreign
key constraint")
I tried to force using the engine "InnoDB" but still not working.
Any tip ?
When you create new migration file laravel automatically added in the start datetime like this 2018_08_10_111004_ for detect which migration must be create firstly. As you show in comments your migration files is 2018_08_31_141536_create_fiches_table.php and 2018_09_03_141649_create_equipes_table.php you must be change one of this migration for firstly called second migration the first. For example
2018_08_31_141536_create_fiches_table.php
2018_08_30_141649_create_equipes_table.php
tl;dr. Solution:
Thanks to Jonas.
the problem was that the tables I was referring as foreign, were not InnoDB.
I added raw SQL statements in alter migrations and then added the foreign keys:
DB::statement("ALTER TABLE table ENGINE='InnoDB';");
Original question
First, before the Stackoverflow police bust me, I know this question is probably 83% of the database of this website. But me is special (Kidding, I know I'm not). But I've tried most of the common stuff and nothing seems to work. So probably I'm overseeing something.
Error
General error: 1215 Cannot add foreign key constraint (SQL: alter table applications add constraint applications_user_id_foreign foreign key (user_id) references users (id) on delete cascade)
This is my migration:
public function up()
{
Schema::create("applications", function(Blueprint $table) {
$table->engine = "InnoDB";
$table->increments('id');
$table->timestamps();
});
Schema::table('applications', function($table) {
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('job_request_id')->unsigned()->index();
$table->foreign('job_request_id')->references('id')->on('job_requests')->onDelete('cascade');
$table->integer('status')->default(0);
});
}
What I've already tried:
1.
public function up()
{
Schema::create("applications", function(Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('job_request_id')->unsigned();
$table->foreign('job_request_id')->references('id')->on('job_requests')->onDelete('cascade');
$table->integer('status')->default(0);
});
}
2.
public function up()
{
Schema::create("applications", function(Blueprint $table) {
$table->engine = "InnoDB";
$table->increments('id');
$table->timestamps();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('job_request_id')->unsigned();
$table->foreign('job_request_id')->references('id')->on('job_requests')->onDelete('cascade');
$table->integer('status')->default(0);
});
}
Splitting the migration into two files (A create and an alter). Even adding each reference one by one.
4.- using DB::statement('SET FOREIGN_KEY_CHECKS=0;'); and =1 at the beginning an the end og the migration.
5.- removing the unsigned() and the index().
Might mean something:
1.- When I rollback the migration, it doesn't delete the table. So if I rollback and migrate, would give me a "already exists error".
2.- I already have migrations which reference the same items, i.e:
Schema::create('job_requests', function (Blueprint $table) {
...
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
...
});
UPDATE
For the drop methods I've tried:
For the create migrations
public function down()
{
Schema::drop('applications');
}
public function down()
{
Schema::dropIfExists('applications');
}
2.- For the alter migrations
public function down()
{
Schema::table('applications', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropColumn('user_id');
$table->dropForeign(['job_request_id']);
$table->dropColumn('job_request_id');
});
}
UPDATE 2:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
public function up()
{
Schema::create('job_requests', function (Blueprint $table) {
$table->increments('id');
$table->integer('status')->default(0);
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('job_requests');
}
I added three more alter migration:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->engine = "InnoDB";
});
}
///////////////////////////
public function up()
{
Schema::table('job_requests', function (Blueprint $table) {
$table->engine = "InnoDB";
});
}
///////////////////////////
public function up()
{
Schema::table('applications', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('job_request_id')->references('id')->on('job_requests')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('applications', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['job_request_id']);
});
}
Without luck yet.
The referenced tables also have to use the InnoDB engine.
You can change them with raw SQL statements:
DB::statement("ALTER TABLE users ENGINE='InnoDB';");
DB::statement("ALTER TABLE job_requests ENGINE='InnoDB';");
for deleting the table:
public function down()
{
Schema::disableForeignKeyConstraints();
Schema::dropIfExists('applications');
}