laravel 5 - How can i add ->index() to existing foreign key - php

Framework: Laravel 5.2
Database: MySQL
PHP: 7.0
I have the table "pops":
Schema::create('pops', function (Blueprint $table) {
$table->string('id')->primary()->index();
$table->string('ab_test_parent_id')->nullable();
$table->string('cloned_parent_id')->nullable();
$table->timestamps();
});
And the table "conversions":
Schema::create('conversions', function (Blueprint $table) {
$table->string('id')->primary()->index();
$table->integer('users')->default(null);
$table->string('name',256)->default(null);
$table->string('pop_id');
$table->foreign('pop_id')->references('id')->on('pops')->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
I have set a foreign key (pop_id) in the "conversions" table. Now does it's mean that the foreign key (pop_id) is also a index? if not... what i need to do in order to make it a index?
Thank?

You can just do this.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddIndexToLeads extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('leads', function(Blueprint $table)
{
$table->index('trader_id');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('leads', function (Blueprint $table)
{
$table->dropIndex(['trader_id']);
});
}
}
credit to #bobbybouwmann

Here is a perfect solution for you.
Up
$table->string('poptin_id')->index('poptin_id');
Down
$table->dropIndex(['poptin_id']);
Suggestion to fix your migrations
$table->string('id')->primary()->index();
replace above with below
$table->increments('id');
and fix your foreign key as below
$table->integer('poptin_id')->index('poptin_id')->unsigned();

I was facing problem when i just write :-
$table->index('column_name');
So to be more exact first you need to create column with desired column type then assign it to be index like this :-
$table->string('column_name');
$table->index('column_name');
//or
$table->string('column_name')->index();
I hope this helps

Laravel only adds a foreign key constraint and doesn't add index implicitly. But some databases such as MySQL automatically index foreign key columns.
If you need to add index to a field in another migration. Then you could do
$table->index('email');

Related

Laravel migration drop column with primary key (error)

I have already checked the other topics but no solution worked with me. I tried the last time:
public function up()
{
if(Schema::hasColumn('orders_products_variations','id')) {
Schema::table('orders_products_variations',function (Blueprint $table) {
$table->unsignedInteger('id')->change();
$table->dropPrimary();
$table->dropColumn('id');
});
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('clients', function (Blueprint $table) {
$table->string('id');
});
}
And the error message is :
SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key (SQL: alter table orders_products_variations drop primary key)
Any idea?
A migration class contains two methods: up and down. The up method is
used to add new tables, columns, or indexes to your database, while
the down method should reverse the operations performed by the up
method.
Dropping Columns
To drop a column, use the dropColumn on the Schema builder inside down method
if (Schema::hasColumn('table_name', 'column_name')) {
Schema::table('table_name', function (Blueprint $table) {
$table->dropColumn('column_name');
});
}
Adding / Dropping Columns
PS When you have to add a new column to the existing table in Laravel, you must
create new migration .
php artisan make:migration add_column_to_table

Migration laravel 5.5 : cannot create table except users table and password_reset table

i have 9 tables, when i run command :
php artisan migrate
only users table, migration table and password_reset table are created in my database. this is my sample code
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAlatsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('alats', function (Blueprint $table) {
$table->increments('id');
$table->integer('merk_id')->unsigned();
$table->integer('kategori_id')->unsigned();
$table->integer('operator_id')->unsigned();
$table->string('nama');
$table->string('no_plat',15);
$table->date('tahun');
$table->string('volume',20);
$table->text('keterangan');
$table->enum('status',['ada','disewa','servis']);
// $table->timestamp('created_at');
// $table->timestamp('updated_at');
$table->timestamps();
$table->foreign('merk_id')->references('id')->on('merks')->onDelete('CASCADE');
$table->foreign('kategori_id')->references('id')->on('kategoris')->onDelete('CASCADE');
$table->foreign('operator_id')->references('id')->on('operators')->onDelete('CASCADE');
});
}
public function down()
{
Schema::dropIfExists('alats');
}
}
please help me..?
The migration files need to be migrated in right order. You can't migrate a table with a non existing foreign key.
You probably have a foreign key in some migration and the id key for that will come to existence later in the next migration file. That is why you get this error.
Check your migration files and watch out on order they get created.
For example if you have a foreign key alats_merk_id_foreign then the migration file with alats_merk_id must be migrated before.
Schema::create('alats', function (Blueprint $table) {
$table->increments('id');
$table->integer('merk_id')->unsigned();
});
Schema::table('alats', function(Blueprint $table)
{
$table->foreign('merk_id')
->references('merk_id')->on('merk_id_table_name')
->onDelete('cascade');
});
First create only table and then create foreign key.
And make sure merk_id_table should migrate first.
if you did every thing in all answers
I think your problem is from the foreign/primary key type and length
so you may create the id as integer and its corresponding foreign key as an integer with different length, or even as another type as string forexample
so try to make integers with unsigned and same length
try to use ->unsigned()->length(10)...
solution:
to make the pimary key and its corresponding foreign key in the same exact type and length
Try doing it like this:
Schema::disableForeignKeyConstraints();
Schema::create('alats', function (Blueprint $table) {
$table->increments('id');
$table->integer('merk_id')->unsigned();
$table->integer('kategori_id')->unsigned();
$table->integer('operator_id')->unsigned();
$table->string('nama');
$table->string('no_plat',15);
$table->date('tahun');
$table->string('volume',20);
$table->text('keterangan');
$table->enum('status',['ada','disewa','servis']);
// $table->timestamp('created_at');
// $table->timestamp('updated_at');
$table->timestamps();
$table->foreign('merk_id')->references('id')->on('merks')->onDelete('CASCADE');
$table->foreign('kategori_id')->references('id')->on('kategoris')->onDelete('CASCADE');
$table->foreign('operator_id')->references('id')->on('operators')->onDelete('CASCADE');
});
Schema::enableForeignKeyConstraints();
You need to replicate the above for every migration.

Updating Existing Column Attributes - Laravel 5 Migration

I have
a existing column called cpe_mac. I created it via migration like this :
$table->string('cpe_mac')->default(NULL)->nullable();
I want
I want to add this ->unique() to that column, without having to drop it and re-add.
I've tried
$table->string('cpe_mac')->unique();
Migration File
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterCaptivePortalTable212017 extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->unique();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->default(NULL)->nullable();
});
}
}
I kept
getting
SQLSTATE[42701]: Duplicate column: 7 ERROR: column "cpe_mac" of relation "captive_portals" already exists
Is there a way to achieve this without having to drop my existing column? I have a lot client data that can't be deleted.
Schema::table('users', function (Blueprint $table) {
$table->string('cpe_mac')->unique()->change();
});
https://laravel.com/docs/5.0/schema#changing-columns
You need to use change() method:
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->unique()->change();
});
Alternatively, you may create the index after defining the column. For example:
$table->unique('email');
https://laravel.com/docs/5.4/migrations#indexes
I had the same issue and this is the solution for Laravel 5.6:
Step1: run this command: composer require doctrine/dbal
step2:run this command:php artisan make:migration THE
-NAME_YOU_WANT --table=TABLENAME
step3: in the added migration, add $table->string('cpe_mac')->unique()->change(); in Schema::table part.
step4: run this command: php artisan migrate
If the column is already defined you can use:
$table->unique('cpe_mac');

Multiple primary keys found issue Laravel

here is the issue. I am banging my head for hours now on this. Laravel is not allowing me to have a primary key (it says multiple but you can see it has only one). And further more as there is issue causing in primary key in teachers table. I am not able to use this as a foreign key in courses table.
Migration file for teacher table
class CreateTeachersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('teachers', function (Blueprint $table) {
$table->increments('teacher_id')->primary();
$table->string('email', 200);
$table->string('first_name',300)->nullable();
$table->string('last_name',300)->nullable();
$table->string('account_status',50)->default('inactive');
$table->string('subscription_status',50);
$table->string('account_reset_code',400)->nullable();
$table->string('passkey',500);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('teachers');
}
}
Migration File for courses table
class CreateCoursesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('courses', function (Blueprint $table) {
$table->increments('course_id')->primary();
$table->integer('teacher_id_fr');
$table->string('course_name', 500);
$table->string('course_code',300);
$table->string('subject_area',300);
$table->string('course_level',100);;
$table->string('grade_periods',100);
$table->timestamps();
});
Schema::table('courses',function(Blueprint $table){
$table->foreign('teacher_id_fr')->references('teacher_id')->on('teachers')->onDelete('cascade')->onUpdate('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('courses');
}
}
Issue raised on migrating
Syntax Error or access violation. 1068 Multiple primary keys found
.
What I've tried by now
1) Making the primary column unsigned using unsigned method.
2) using InnnoDB engine type for table.
3) And much other things as suggested for similiar posts on the forums but nothing seems to work for me.
EDIT
I've removed the primary() method from both files at $table->increments('teacher_id'). As this is said Laravel marks auto increments columns as primary keys.
But now the error is on courses table as it says.
General error : 1215 cannot add foreign key constraint
You can define Multiple primanry key in migration file as below:
$table->primary(array('field_name1', 'field_name2'));
Try to replace this, remove primary(), increments automatically creates it primary
$table->increments('teacher_id')->primary();
to
$table->increments('teacher_id');
For new error try this General error : 1215 cannot add foreign key constraint
public function up()
{
Schema::create('courses', function (Blueprint $table) {
$table->increments('course_id');
$table->integer('teacher_id_fr');
$table->string('course_name', 500);
$table->string('course_code',300);
$table->string('subject_area',300);
$table->string('course_level',100);;
$table->string('grade_periods',100);
$table->timestamps();
$table->foreign('teacher_id_fr')
->references('teacher_id')->on('teachers')
->onDelete('cascade')
->onUpdate('cascade');
});
}
I was able to fix the issue with a minute change. I modified courses migration file like below and it worked like a charm
$table -> integer('teacher_id_fr') -> unsigned();
Reason
Actually both the referenced and referencing columns (teacher.teacher_id and course.teacher_id_fr in this case) must be of same type.
Having said that, Laravel marks autoincrement columns as "Primary" and of type unsigned. So make sure to change foregin key column to match the type of primary key i.e unsigned. which the above modification does.
Hope it clarifies the issue and solution. If you have anything else on your mind. Please give it a shot here.
Happy Learning!

Dropping column with foreign key Laravel error: General error: 1025 Error on rename

I've created a table using migration like this:
public function up()
{
Schema::create('despatch_discrepancies', function($table) {
$table->increments('id')->unsigned();
$table->integer('pick_id')->unsigned();
$table->foreign('pick_id')->references('id')->on('picks');
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
$table->integer('original_qty')->unsigned();
$table->integer('shipped_qty')->unsigned();
});
}
public function down()
{
Schema::drop('despatch_discrepancies');
}
I need to change this table and drop the foreign key reference & column pick_detail_id and add a new varchar column called sku after pick_id column.
So, I've created another migration, which looks like this:
public function up()
{
Schema::table('despatch_discrepancies', function($table)
{
$table->dropForeign('pick_detail_id');
$table->dropColumn('pick_detail_id');
$table->string('sku', 20)->after('pick_id');
});
}
public function down()
{
Schema::table('despatch_discrepancies', function($table)
{
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
$table->dropColumn('sku');
});
}
When I run this migration, I get the following error:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1025 Error on rename of
'./dev_iwms_reboot/despatch_discrepancies' to
'./dev_iwms_reboot/#sql2-67c-17c464' (errno: 152) (SQL: alter table
despatch_discrepancies drop foreign key pick_detail_id)
[PDOException]
SQLSTATE[HY000]: General error: 1025 Error on rename of
'./dev_iwms_reboot/despatch_discrepancies' to
'./dev_iwms_reboot/#sql2-67c-17c464' (errno: 152)
When I try to reverse this migration by running php artisan migrate:rollback command, I get a Rolled back message, but it's not actually doing anything in the database.
Any idea what might be wrong? How do you drop a column that has a foreign key reference?
You can use this:
Schema::table('despatch_discrepancies', function (Blueprint $table) {
$table->dropForeign(['pick_detail_id']);
$table->dropColumn('pick_detail_id');
});
If you take a peak at dropForeign source, it will build the foreign key index name for you if you pass the column name as an array.
It turns out; when you create a foreign key like this:
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
Laravel uniquely names the foreign key reference like this:
<table_name>_<foreign_table_name>_<column_name>_foreign
despatch_discrepancies_pick_detail_id_foreign (in my case)
Therefore, when you want to drop a column with foreign key reference, you have to do it like this:
$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign');
$table->dropColumn('pick_detail_id');
Update:
Laravel 4.2+ introduces a new naming convention:
<table_name>_<column_name>_foreign
Update:
Larave > 8.x introduces a new function
dropConstrainedForeignId('pick_detail_id');
This will delete the column as well as the foreign key of the column
I had multiple foreign keys in my table and then I had to remove foreign key constraints one by one by passing column name as index of the array in down method:
public function up()
{
Schema::table('offices', function (Blueprint $table) {
$table->unsignedInteger('country_id')->nullable();
$table->foreign('country_id')
->references('id')
->on('countries')
->onDelete('cascade');
$table->unsignedInteger('stateprovince_id')->nullable();
$table->foreign('stateprovince_id')
->references('id')
->on('stateprovince')
->onDelete('cascade');
$table->unsignedInteger('city_id')->nullable();
$table->foreign('city_id')
->references('id')
->on('cities')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('offices', function (Blueprint $table) {
$table->dropForeign(['country_id']);
$table->dropForeign(['stateprovince_id']);
$table->dropForeign(['city_id']);
$table->dropColumn(['country_id','stateprovince_id','city_id']);
});
}
Using below statement does not work
$table->dropForeign(['country_id','stateprovince_id','city_id']);
Because dropForeign does not consider them seperate columns that we want to remove. So we have to drop them one by one.
The key (for me) to solving this was to make sure that the $table->dropForeign() command was being passed the right relationship name, not necessarily the column name. You do not want to pass the column name, as would be much more intuitive IMHO.
What worked for me was:
$table->dropForeign('local_table_foreign_id_foreign');
$table->column('foreign_id');
So the string I passed to dropForeign() that worked for me was in the format of:
[local table]_[foreign key field]_foreign
If you have access to a tool like Sequel Pro or Navicat, being able to visualize those will be very helpful.
Something that occurred to me was that I didn't know where to put the Schema::table block.
Later I discovered that the key is on the SQL error:
[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table if exists `lu_benefits_categories`)
So the Schema::table block needs to go in the down() function of the lu_benefits_categories migration and before the Schema::dropIfExists line:
public function down()
{
Schema::table('table', function (Blueprint $table) {
$table->dropForeign('table_category_id_foreign');
$table->dropColumn('category_id');
});
Schema::dropIfExists('lu_benefits_categories');
}
After that, the php artisan migrate:refresh or php artisan migrate:reset will do the trick.
on laravel 8 use dropConstrainedForeignId
(https://github.com/laravel/framework/pull/34806)
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddAddressFieldsInEventTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('events', function (Blueprint $table) {
$table->bigInteger('address_id')->nullable();
$table->foreign('address_id')
->references('id')
->on('addresses')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('events', function (Blueprint $table) {
$table->dropConstrainedForeignId('address_id');
$table->dropColumn('address_id');
});
}
}
You can disable relation id first
Schema::disableForeignKeyConstraints();
In Laravel > 8.x you can use the following code to add/remove foreign keys. You will need to drop the foreign key before dropping the column, as otherwise, the foreign key could cause the error your encountering.
Add foreign key
$table->foreignId('pick_id')->constrained('picks')->cascadeOnUpdate()
->cascadeOnDelete();
Drop foreign key
$table->dropConstrainedForeignId('pick_id');

Categories