laravel6: how to change references of a foreign key with migration - laravel

I have tried to change foreign key reference by dropforeign key.I think everything is ok but i get this error:
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP
FOREIGN KEY teacher_schedule_calendars_product_id_foreign; check
that it exists (SQL: alter table teacher_schedule_calendars drop
foreign key teacher_schedule_calendars_product_id_foreign)
How can I solve it?
my migration code is :
Schema::table('teacher_schedule_calendars', function (Blueprint $table) {
$table->dropForeign(['product_id']);
$table->foreign('product_id')->references('id') ->on('courses')->onDelete('cascade');
});
firstly, I ave removed the foreign and then add references. but it did not work.

I'm assuming you created a foreign key on the product_id column in a previous migration and you simply want to renew it or replace it with a foreign key to another table. In this case, what you are attempting to do might be problematic due to the way how migrations work and how individual database grammatics translate the commands.
What you can do to mitigate the issue is splitting the commands into two Schema::table($table) blocks:
Schema::table('teacher_schedule_calendars', function (Blueprint $table) {
$table->dropForeign(['product_id']));
});
Schema::table('teacher_schedule_calendars', function (Blueprint $table) {
$table->foreign('product_id')->references('id')->on('courses')->onDelete('cascade');
});

Related

Laravel migration mix up with person/people table names

For some reason Laravel is getting mixed up pluralizing person/persons some reason it assumes my table is people.
I know how to get around this without manually specify the table name inside the $table->foreignId('person_id')->constrained('persons') but I wanted to know why it happens? And which tables names to avoid/watch out for.
Can't create table
person_logs (errno: 150 "Foreign key constraint is incorrectly
formed") (SQL: alter table person_logs add constraint
person_logs_person_id_foreign foreign key (person_id) references
people (id))
Schema::create('persons', function (Blueprint $table) {
$table->id('id');
$table->string('firstname');
$table->string('lastname');
});
Schema::create('person_logs', function (Blueprint $table) {
$table->id('id');
$table->string('example');
$table->foreignId('person_id')->constrained();
});
Down the hood it calls Str::plural() on person as part of person_id, the plural version of this is people. So the correct naming according to the Laravel convention for your persons table is actually people.
So change the table to people or constrained() first parameter is the table name.
$table->foreignId('person_id')->constrained('persons');

Laravel Database Migration Column altered to Unique and Nullable causing error

I am attempting to integrate social logins with my existing laravel app. I am attempting to change email and password to nullable but I also need email to remain unique. On executing my migration I am getting an error for duplicate key name 'users_email_unique'
Laravel 5, already fixed the issue with enum I had for altering a column.
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique()->nullable()->change();
$table->string('password')->nullable()->change();
});
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique' (SQL: alter table users add unique users_email_unique(email))
Exception trace:
1 Doctrine\DBAL\Driver\PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique'")
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:119
2 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique'")
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:117
Edit
If I remove Unique() from email, will it remain unique since that was previously set in a different migration?
You can change the uniqueness behaviour in a new migration by following below:
public function up()
{
Schema::table('contacts', function (Blueprint $table) {
$table->dropUnique(['email']);
});
}
/**
* Reverse the migrations.
*
*/
public function down()
{
Schema::table('contacts', function (Blueprint $table) {
$table->string('email')->unique()->change();
});
}
The Nullable() attribute will stay with the email column, since it was created with it.
It sound like the database is detecting a repeated value. That's impossible with nulls, so it could be an empty string maybe.
If that's the case, you can write a mutator function in your model to check if the value is empty and, set it to null before it goes to the database engine, like this:
public function setNameOfYourAttribute($value) {
if ( empty($value) ) {
$this->attributes['nameofyourattribute'] = NULL;
}
}
Hope it helps.
NOTE:
Full Documentation
Figured this out myself, as mentioned in the comment on the above answer.
Simply because the table was already created with unique() if I remove that it will allow the migration and will also persist the unique() functionality that was in the original User table migration.

onDelete Cascade two sides

I'm using Laravel Framework, I have multiple connected tables, I successfully could remove a operation from operations table when the related transaction is deleted from transactions table, but i couldn't get it to work in the opposite side, as it throws an error on migration and also when adding new rows to operations table.
Schema::create('operations', function (Blueprint $table) {
$table->increments('id');
$table->integer('car_id')->unsigned();
$table->string('operation');
$table->integer('transaction')->unsigned();
$table->timestamps();
});
Schema::table('operations', function($table) {
$table->foreign('car_id')->references('id')->on('cars')->onDelete('cascade');
$table->foreign('transaction')->references('id')->on('transactions')->onDelete('cascade');
});
What I need is to also delete the transaction when a related operation is deleted:
Schema::create('transactions', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->string('status')->index();
$table->date('date')->index();
$table->string('user_added');
$table->string('note')->nullable();
$table->timestamps();
});
Schema::table('transactions', function($table) {
$table->foreign('id')->references('transaction')->on('operations')->onDelete('cascade');
});
Is there a way to achieve that?
For now it throws an error on migration:
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key
constraint (SQL : alter table transactions add constraint
transactions_id_foreign foreign key (i d) references
operations (transaction) on delete cascade)
Which is normal because operations table comes after transactions in order, even if i put the second part of the code in operations table, it throws a similar error when i start inserting rows to table.
I appreciate leading me to a solution.
its looks like you added your primarykey as foreignkey
Schema::table('transactions', function($table) {
$table->foreign('id')->references('transaction')->on('operations')->onDelete('cascade');
please adding 1 column on transaction table "operations_id" and change your schema like this
Schema::table('transactions', function($table) {
$table->foreign('operations_id')->references('id')->on('operations')->onDelete('cascade');

Foreign key constraint is incorrectly formed with Composite Keys

I have a table "theaters". In which (theater_name,area_name,station) are composite key.And in the table "cubelists" I have columns (thtr_name,area,stn) which are to be referred to (theater_name,area_name,station) of table "theaters".
The problem here is the combination of the columns - (theater_name,area_name,station) in table "theaters" is unique as it is a composite key. But each column separately is not unique.
Then how can I refer these columns from table "cubelists"?
Schema::create('theaters', function (Blueprint $table) {
$table->string('theater_name');
$table->string('area_name');
$table->string('station');
$table->primary(array('theater_name','area_name','station'));
$table->text('address');
$table->bigInteger('phno');
$table->string('contact_person');
});
public function up()
{
//
Schema::create('cubelists', function (Blueprint $table) {
$table->string('mvie_name');
$table->foreign('mvie_name')->references('movie_name')->on('movies');
$table->string('thtr_name');
$table->string('area');
$table->string('stn');
$table->foreign(array('thtr_name','area','stn'))-
>references(array('theater_name','area_name','station'))-
>on('theaters');
$table->primary(array('mvie_name','thtr_name','area','stn'));
$table->string('type');
$table->string('subtype');
$table->date('validity');
$table->string('show');
});
}
If I give the above code I get an error as
Migration table created successfully.
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table `boras_cachii`.`#sql-a10_
112` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter tabl
e `agreements` add constraint agreements_area_name_foreign foreign key (`area_nam
e`) references `cubelists` (`area`))
[PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create table `boras_cachii`.`#sql-a10_
112` (errno: 150 "Foreign key constraint is incorrectly formed")
You must first create the table, then foreign keys.
Schema::create('cubelists', function (Blueprint $table) {
$table->string('mvie_name');
$table->string('area');
$table->string('stn');
$table->primary(array('mvie_name','thtr_name','area','stn'));
$table->string('type');
$table->string('subtype');
$table->date('validity');
$table->string('show');
$table->foreign(array('thtr_name','area','stn'))
->references(array('theater_name','area_name','station'))
->on('theaters');
$table->foreign('mvie_name')
->references('movie_name')
->on('movies');
});
Also theaters table must migrate first since cubelists is referencing it. And make sure that the foreign key column and the referencing column are the same type or length.

cannot add foreign key constraint Laravel 5.1

I first created all the tables without their foreign keys, I then added the foreign keys for each table, starting with the first table, i got this error:
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `accounts` add constraint accounts_client_id_foreign foreign
key (`client_id`) references `clients` (`id`))
Here's my code:
public function up()
{
Schema::create('accounts', function(Blueprint $table)
{
$table->engine = 'InnoDB';
$table->bigInteger('id');
$table->integer('client_id')->unsigned();
$table->foreign('client_id')->references('id')->on('clients');
$table->integer('emp_id')->unsigned();
$table->foreign('emp_id')->references('id')->on('employees');
$table->string('type');
$table->timestamps();
});
}
I tried without $table->engine='innoDB'; but same error
Plus, i tried to separate the foreign keys:
Schema::table('accounts', function($table) {
$table->foreign('client_id')->references('id')->on('clients');
$table->foreign('emp_id')->references('id')->on('employees');
});
I got this error:
Base table or view already exists: 1050 Table 'accounts' already exists
So when I deleted and re-migrate i get the first error
So whats happening?
I've got same error, it feels like bug to me. What I did is created different migrations for foreign keys. So, first you create table with fields, then (in next by date migration) you add foreign keys.
Then I rolled back all migrations and reruned them with php artisan migrate. It worked for me, I hope it'll also work for you.
I foresee you created the related table("clients") specifying the primary key/id as this
$table->bigInteger('id');
or
$table->integer('id');
which will cause problem in the sense that your foreign key constraint
is being specified as
$table->integer('client_id')->unsigned();
whiles the primary key/id does not have the unsigned() constraint assigned to it.
So change the primary key of the related table to
$table->bigInteger('id')->unsigned();
or
$table->integer('id')->unsigned();
And if you are using bigInteger for the primary key try and make the foerign key also bigInteger. Don't forget to use unsigned() for both (the primary key and the foreign key).

Resources