How to use nullable in foregin in Laravel? - laravel

I create migration in laravel 5.6.
I need add user information if the user was logged in my website else add 0 in column.
My code is:
$table->integer('user_id')->default(0);
$table->foreign('user_id')->references('id')->on('users');
But aftre run migrate show this error:
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
I need add default 0 or null in column or add user_id in column if the user was logged in my website.
How to issue this problem?

You need to make it unsigned and nullable. Also, it's a good idea to separate creating a column and adding foreign key logic to avoid similar errors:
Schema::create('table_name', function (Blueprint $table) {
$table->unsignedInteger('user_id')->nullable();
});
Schema::table('table_name', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users');
});

Data type will be diffrent for both user_id and id in users table.
$table->integer('user_id')->unsigned()->nullable();
Primary keys created using in increments() will be unsigned integer

Use this short method
$table->foreignId('user_id')
->constrained()
->onUpdate('cascade')
->onDelete('cascade');
Laravel is smart enough to know that you are referencing to the users table

$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
try this

Related

how to solve this erorr SQLSTATE[HY000]: General error: 1005 Can't create table

I have this error when run migration
SQLSTATE[HY000]: General error: 1005 Can't create table tms-app.#sql-1e64_2b (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table projects add constraint projects_cout_id_foreign foreign key (cout_id) references couts (id) on update cascade)
this is projects table:
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->string('libelle');
$table->string('libelle_long');
$table->string('direction');
$table->integer('cout_id')->unsigned();
$table->foreign('cout_id')
->references('id')->on('couts')
->onUpdate('cascade');
$table->foreign('status')
->referenecs('id')->on('statuses')
->onUpdate('cascade')
->onDelete('cascade');
$table->timestamps();
});
Sometimes this error happens, when we define foreign key and you should use bigInteger('') or use unsignedBigInteger('').
Use the code below:
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->string('libelle');
$table->string('libelle_long');
$table->string('direction');
$table->bigInteger('cout_id')->unsigned();
$table->bigInteger('status')->unsigned();
$table->foreign('cout_id')->references('id')->on('couts')->onDelete('cascade');
$table->foreign('status')->references('id')->on('statuses')->onDelete('cascade');
$table->timestamps();
});
Note: In tables couts & statuses change the id field $table->increments('id'); to $table->bigIncrements('id');
This error should be casuses by the following miss-configuration below I mentioned, be sure all of them to be configured correctly
1: Laravel migration foriegn key should be assgined as bigInteger or unsignedBigInteger
example:
$table->unsignedBigInteger('user_id');
or
$table->bigInteger('user_id')->unsigned();
and for assigning foriegn key attribute you should do
$table->foriegn('user_id')->reference('id')->on('users'); // if you need further attribtute you can chain to this line
2: be sure that the order of migration file is formed correclty because Laravel will migrate table based on timestamp for example if need a foreign key from user table first you need to create user table then the child table the timestamp of users table should be older than child (even 1 second)

laravel migration foreign key nullable

I'm building a project with Laravel version 7.25.0. I coded my migration files and they contain some foreign keys. I added nullable() at the end of each foreign key but they don't work. I looked at similar questions but none of them solved my problem. Here is my migration file's up function
{
Schema::create('tests', function (Blueprint $table) {
$table->id();
$table->string('title')->nullable();
$table->tinyInteger('level')->nullable();
$table->tinyInteger('try_count')->nullable();
$table->char('room_name')->nullable();
$table->boolean('timeless')->nullable();
$table->integer('time')->nullable();
$table->foreignId('school_id')->constrained('schools')->nullable();
$table->foreignId('year_id')->constrained('years')->nullable();
$table->foreignId('course_id')->constrained('courses')->nullable();
$table->string('type')->nullable();
$table->date('start_date')->nullable();
$table->date('end_date')->nullable();
$table->time('start_time')->nullable();
$table->time('end_time')->nullable();
$table->text('description')->nullable();
$table->boolean('timeout')->nullable();
$table->boolean('question_sorting')->nullable();
$table->timestamps();
});
}
when I migrate it with the other files and not getting any error, this is my phpmyadmin page of that table
phpadmin page table ss
Any additional column modifiers must be called before constrained,
So You must put the nullable() before constrained() like this :
$table->foreignId('course_id')->nullable()->constrained('courses');

Issues with foreign constraints -

I tried to follow the documentation of laravel and laracasts, however I get an error in my migrations concerning foreign keys.
I have articles about games that are written by authors (users), so I want the user Id for the article.
This is my games table:
public function up()
{
Schema::create('games', function (Blueprint $table) {
$table->id('id');
$table->timestamps();
$table->string('name', 100);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->text('description');
$table->string('publisher');
$table->string('url');
});
}
And this my user table:
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();
});
}
If I understand correct I name the column in the games table 'user_id', and it references to the Id of the user, which is called 'id' in the user table?
When migrating however i get the error theres no user_id.
SQLSTATE[42000]: Syntax error or access violation: 1072 Key column 'user_id' doesn't exist in table (SQL: alter table gamesadd constraintgames_user_id_foreign foreign key (user_id) references users (id) on delete cascade)
Can someone tell me what I am doing wrong? Am I mixing up where I should refer to 'id' in the user table?
Migrations by default are run with the same order that they are been created, and in your case, the games migration is been executed before the user migration, and so you when migrating the games migration, there is no user table, and so
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Will fail.
In order to solve this problem, rename the user migration with a date before the one that has the games migration
Thanks to #lagbox for having pointed it out:
This line is not creating a new field, but is just adding a constrain
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Instead you should first create the field and then create the constrain:
$table->bigInteger('user_id)->...;
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
The way I usually do it is :
Creating the migrations files (containing all the fields)
Creating alterations files (adding FK)
Like that, when I run php artisan migrate the order of the migrations doesn't block anything.
With your code above you are trying to add a foreign constraint on a field which doesn't exist yet

Migrations - Duplicate key on write or update - Only for Test Env

A project I am working on uses a mysql db for both testing & development (different db). When running php artisan migrate:refresh everything works fine.
However, when running tests it fails to run all migrations with the following error:
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1005 Can't create table `cmstatic_test`.`#sql-5008_121` (errno: 121 "Duplicate key on write or update") (SQL: alter table `project_user` add constraint `project_user_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)
Here is my migration up method
public function up()
{
Schema::create('project_user', function (Blueprint $table) {
$table->unsignedBigInteger('project_id');
$table->foreign('project_id')
->references('id')->on('projects')
->onDelete('cascade');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->unsignedBigInteger('role_id');
$table->foreign('role_id')
->references('id')->on('roles');
$table->timestamps();
});
}
I don't get how there can be a duplicate key set for this table.
My tests look like
use Illuminate\Foundation\Testing\RefreshDatabase;
class AuthTest extends TestCase
{
use RefreshDatabase;
...
Update:
if I remove
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
The tests can be run again. However, I want that foreign key relation -.-
Update2:
I checked the table structure after removing the line that adds the foreign key and obviously the foreign key is not set. So no other migration is doing the same.
In my case I had 2 tables
page_translations
pr_page_translations
I had all sympthoms described in 1st post. I don't believe there can be an "error" in DB. So I searched and found the cause.
There was a foreign key named "page_translations_page_id_foreign" in table #1. When I was trying to add FK with same name to tabe #2 I got my "duplicate" error. So I added "pr_" prefix to FK name in table #2 "pr_page_translations_page_id_foreign".
Another solution that also worked for me was to rename already existing FK in table #1.
Conclusion: FK names across all tables must be unique.
After this I searched for explanation, and here it is: Why do MySQL foreign key constraint names have to be unique?
Try this:
public function up()
{
if (!Schema::hasTable('project_user')) {
Schema::create('project_user', function (Blueprint $table) {
$table->unsignedBigInteger('project_id');
$table->foreign('project_id')
->references('id')->on('projects')
->onDelete('cascade');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->unsignedBigInteger('role_id');
$table->foreign('role_id')
->references('id')->on('roles');
$table->timestamps();
});
}
}
It seems like there was an error with my database itself. I've deleleted the tables multiple times and tried it again and the error was still there.
However, deleting the whole database and re-creating it solved the
issue.
This might be interesting for anyone facing this issue aswell.

Laravel :Foreign key constraint in incorrectly formed

I think everything i wrote correctly.When i run "php artisan migrate" command PDOException appear.I went through all over relevant post in stackoverflow.But i am not getting any solution.
enter image description here
[PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create table laravel_jobs.#sql-
ec4_170 (errno: 150 "Foreign key constraint is incorrectly formed")
The error: Can't create table laravel_jobs
So I don't think the problem is with the Resume table migration.
you should create your foreign keys after creating the table. like this:
public function up()
{
Schema::enableForeignKeyConstraints();
Schema::create('user', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->uuid('id');
$table->primary('id');
$table->string('class_code');
$table->string('username')->nullable();
$table->string('email_address')->nullable();
$table->uuid('contact_id')->nullable();
$table->uuid('customer_id')->nullable();
$table->char('password_hash', 64)->nullable();
$table->boolean('active')->nullable();
$table->string('remember_token', 100)->nullable();
$table->timestamps();
});
Schema::table('user', function(Blueprint $table) {
$table->foreign('contact_id')->references('id')->on('contact')->onDelete('cascade')->onUpdate('cascade');
$table->foreign('customer_id')->references('id')->on('customer')->onDelete('cascade')->onUpdate('cascade');
});
}
you may however need to ensure the order that your migrations are ran is correct. Therefore you may want your create table function to create nullable foreign keys.
I think you need to update your migration code like :
Schema::create('resume', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id')->unsigned()->index();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamp();
});
Hope this work for you!
Check the following terms:
1. The datatype of id column on users table and user_id on resume table are same.
2. If id is unsigned integer or big integer then user_id will be unsigned
integer or big integer.
3. Length of id on users table and user_id on resume table will be same.
Hope this solves your problem.
here is the answer for your question the user #lalitesh already found the solution
laracast
i hope you find your solution

Resources