Rollback of new column deletes the entire table - php

I am trying to rollback updated column in my database table using migrations in laravel 4.2.
public function up()
{
if (Schema::hasTable('payments') && !Schema::hasColumn('payments', 'updated_at')) {
Schema::table('payments', function (Blueprint $table) {
$table->dateTime('updated_at')->nullable();
});
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
if (Schema::hasTable('payments')) {
Schema::table('payments', function (Blueprint $table) {
Schema::drop('updated_at');
});
}
}
When I do it this way it shows me that updated_at table doesnt exist:
Schema::drop('updated_at');
Doing it this way deleted the entire table:
Schema::drop('payments', 'updated_at');
How is it supposed to look like then?
Thank you and best wishes!

Schema::drop('updated_at'); is telling the DB to drop the updated_at table, which obviously doesn't exist. You need to use $table->dropColumn('updated_at') to drop a column on a specific table. See below:
public function down(){
if (Schema::hasTable('payments')) {
Schema::table('payments', function (Blueprint $table) {
$table->dropColumn('updated_at');
});
}
}
You can see you are already in the Schema::table("payments" ...) function, so using $table->dropColumn() will attempt to drop the column from the payment table.

Use the $table variable:
Schema::table('payments', function($table)
{
$table->dropColumn('updated_at');
});

Related

In Eloquent how would I check if a table row is associated with another?

Before I get into what my issue is, here is my setup. (FYI I am stuck using Laravel 7.4 at the moment so SOS):
Applications Table
public function up()
{
Schema::create('applications', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
Reports Table
public function up()
{
Schema::create('reports', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
ApplicationReports Table (I know the naming convention is off, but this is how I have to do it for code base)
public function up()
{
Schema::create('applicationReports', function (Blueprint $table) {
$table->unsignedInteger('application_id')->nullable(false);
$table->unsignedInteger('report_id')->nullable(false);
});
}
Here is an example of the ApplicationReports table
application_id
report_id
200
2
Then I have a many to many relationship setup between the Applications and Reports tables like so:
Applications Model
public function reports() {
return $this->belongsToMany(Report::class, 'applicationReports');
}
Reports Model
public function applications() {
return $this->belongsToMany(Application::class, 'applicationReports');
}
In the ReportsController I have a method that will pull all the reports that are in the reports table and then return them, that method looks a little bit like the code below (pseudo coded some of it). But what I am trying to do is only add reports that are associated with applications to the list. When I try the code below doing $report->applications->has($report->id) its returning false and I can't for the life of me figure it out.
public function getReports() {
//Pseudo codeish right here, sorry.
$reports = gets all reports->with(['applications'])->orderBy('name')->get();
$reportsList = [];
foreach ($reports as $report) {
if ($report->applications->has($report->id)) {
$reportsList[] = $report;
}
}
return $reportList;
}
If I dd $report->applications the relationship is there and I can see it under #relations -> #attributes, any help would be appreciated!
The has function is very straight forward.
You can query your reports that only contains applications by doing:
$reports = Report::with('applications')->has('applications')->get();
return $reports;
in other way you can also use whereHas this will accepts Query Builder that you can pass through.
For example:
$reports = Report::with('applications')
->whereHas('applications', function(Builder $query) {
$query->orderBy('created_at');
})->get();
return $reports;

Laravel change String Boolean value to Int Boolean in migration

I'm working with a Laravel project that has two existing columns that are set to strings and hold a visually pleasing Boolean value of true or false.
I'm trying to change these columns from string to boolean in a Laravel migration, but need to convert the existing values in the columns, for instance, if the column value for a record has the value of false, it needs to become 0.
My current migration to modify these columns doesn't seem to acheive this automatically, how can I achieve this?
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddColumnsToNotificationContactsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('notification_contacts', function (Blueprint $table) {
$table->boolean('canNotify')->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('notification_contacts', function (Blueprint $table) {
//
});
}
}
I get:
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'false' for column 'canNotify' at row 1 (SQL: ALTER TABLE notification_contacts CHANGE canNotify canNotify TINYINT(1) NOT NULL)
Do it in multiple steps instead of running it in a single operation.
Steps are:
Add a new temp Column canNotifyTemp
Populate it with the old data from Column canNotify
Delete the old column
Rename the temp column
class UpdateClientsTableAddRedesignColumns extends Migration
{
public function up()
{
// step 1
Schema::table('notification_contacts', function(Blueprint $table) {
$table->boolean('canNotifyTemp')->default(0);
});
// step 2
DB::table('notification_contacts')
->where('canNotify', 'true')
->update(["canNotifyTemp" => true]);
DB::table('notification_contacts')
->where('canNotify', 'false')
->update(["canNotifyTemp" => false]);
// step 3
Schema::table('notification_contacts', function(Blueprint $table) {
$table->dropColumn('canNotify');
});
// step 4
Schema::table('notification_contacts', function(Blueprint $table) {
$table->renameColumn('canNotifyTemp', 'canNotify');
});
}
public function down()
{
// step 4 rollback
Schema::table('notification_contacts', function (Blueprint $table) {
$table->renameColumn('canNotify', 'canNotifyTemp');
});
// step 3 rollback
Schema::table('notification_contacts', function (Blueprint $table) {
$table->string('canNotify')->default('false');
});
// step 2 rollback
DB::table('notification_contacts')
->where('canNotifyTemp', true)
->update(["canNotify" => 'true']);
DB::table('notification_contacts')
->where('canNotifyTemp', false)
->update(["canNotify" => 'false']);
// step 1 rollback
Schema::table('notification_contacts', function (Blueprint $table) {
$table->dropColumn('canNotifyTemp');
});
}
}
Note: I did not run the migration so if there is any problem, tell me.

How to add multiple columns in already made table in Laravel?

I want to add multiple number of columns in the already made table in Laravel . How can i add multiple columns ?
I don't know how to do add columns in my table. I can only add single column one at a time.
Below given is my migration table up function.
public function up()
{
Schema::create('matches', function (Blueprint $table) {
$table->increments('id');
$table->string('sports');
$table->string('match');
$table->string('date');
$table->string('time');
$table->string('teamA');
$table->longtext('teamA_flag');
$table->string('teamB');
$table->longtext('teamB_flag');
$table->string('venue');
$table->string('status');
$table->timestamps();
});
}
This is my table whose name is matches. I want to add two columns using Laravel. The name of columns are: email and qualification.
I am expecting to add multiple number of columns on the table (matches).
I want to add multiple number of columns in the already made table in Laravel . How can i add multiple columns ?
I don't know how to do add columns in my table. I can only add single column one at a time.
Create migration first by php artisan make:migration alter_table_matches,
open migration that is created by the command.
public function up()
{
Schema::table('matches', function (Blueprint $table) {
$table->string('email')->nullable()->default(null);
$table->string('qualification')->nullable()->default(null);
});
}
then in down function
public function down()
{
Schema::table('matches', function (Blueprint $table) {
$table->dropColumn('email');
$table->dropColumn('qualification');
});
}
You can just run:
php artisan make:migration add_first_item_and_second_item_and_next_item_to_matches
This creates a migration file, you can then add:
public function up()
{
Schema::table('products', function (Blueprint $table) {
$table->string('first_item');
$table->string('second_item');
$table->string('next_item');
});
}
public function down()
{
Schema::table('products', function (Blueprint $table) {
$table->dropColumn('first_item');
$table->dropColumn('second_item');
$table->dropColumn('next_item');
});
}
I hope this solves your problem
You can add new columns by creating a new migration.
Remember to make the name of the migration as descriptive as possible.
2021_09_06_083822_update_email_column_and_add_agency_id_and_contact_source_id_in_contacts_table.php
class UpdateEmailColumnAndAddAgencyIdAndContactSourceIdInContactsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('contacts', function (Blueprint $table) {
$table->string('email')->nullable();
$table->integer('agency_id')->after('country_id')->references('agentid')->on('byt_agents');
$table->foreignId('contact_source_id')->after('agency_id')->nullable()->constrained();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('contacts', function (Blueprint $table) {
$table->dropColumn(['agency_id', 'email']);
$table->dropForeign(['contact_source_id']);
});
}
}
If you want to add multiple columns to an already existing table you can follow above answer-thread
but In that case, your all columns will be added at the end of already existing columns
so, In order to add multiple columns after a certain column. You can add columns group by using callback/closure as shown in the below snippet:
class AddFieldsInMatches extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('matches', function (Blueprint $table) {
// closure to add multiple-columns after `id` column
$table->after('id', function ($table) {
$table->integer('email')->nullable();
$table->integer('qualification')->nullable();
});
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('matches', function (Blueprint $table) {
$table->dropColumn('email');
$table->dropColumn('qualification');
});
}
}
Note:
Make sure these columns must be nullable otherwise, you will get an error on running php artisan migrate command on the terminal
callback/closure approach is applicable after Laravel 8.27 versions.
Reference Article: click here
Other StackOverFlow threat: click here

Create a column and in the same time update with Schema Builder in Laravel

in Laravel using Schema Builder
how i can create a column and in the same time update his value whit the other value of the same table?
Its possible?
Thanks
Pseudo code
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSkuToWaranties extends Migration {
public function up()
{
Schema::table('my_table_name', function(Blueprint $table) {
$table->text('my_table_column');
///////////////////////
$table->my_table_column = $table->my_other_table_column;
///////////////////////
});
}
public function down()
{
Schema::table('my_table_name', function(Blueprint $table) {
$table->dropColumn('my_table_column');
});
}
}
Yes that is possible. You can do it like this:
DB::table('my_table_name')
->update(array('my_table_column' => DB:raw('my_other_table_column')));
With this, you are using Laravel's Query Builder. It actually builds this query for you:
update my_table_name set my_table_column = my_other_table_column
Another solution is to just execute this raw query:
DB::update('update my_table_name set my_table_column = my_other_table_column');
As #lukasgeiter mentioned in a comment, you must place this code outside the closure, so this becomes the new up() method:
public function up()
{
Schema::table('my_table_name', function(Blueprint $table) {
$table->text('my_table_column');
});
DB::table('my_table_name')
->update(array('my_table_column' => DB:raw('my_other_table_column')));
}

With Laravel Migration, How to change data type of a column and update its existing data to fit the new data type, without using raw SQL queries?

Suppose I have a users table which has been created through Migration and Schema Builder, like this:
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id')->unsigned();
$table->string('name', 50);
$table->string('email', 50)->unique();
$table->string('password', 100);
$table->enum('is_suspended', ['yes', 'no'])->default('no');
$table->timestamps();
});
}
public function down()
{
Schema::drop('users');
}
Now suppose I want to change data type of the column is_suspended from enum to boolean without using raw SQL queries, and also fill the new boolean column with 0 instead of the enum value no and 1 instead of enum vlaue yes, How can I do this with migration in Laravel framework?
Here is how I performed this:
The up() method:
...
use App\User;
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
// do the following steps in order:
// 1- add a new column with the desired data type to the table
// 2- fill the new column with the appropriate data
// 3- delete the old column
// 4- rename the new column to match name of the deleted column
Schema::table('users', function(Blueprint $table)
{
// 1- add a new column with the desired data type to the table
// note that after() method is used to order the column and works only with MySQL
$table->boolean('is_suspended_new')->default(0)->after('is_suspended');
});
// 2- fill the new column with the appropriate data
// note that you may need to use data in the old column as a guide (like in this example)
$users = User::all();
if ($users) {
foreach ($users as $user) {
$u = User::find($user->id);
if ($u->is_suspended === 'yes') {
$u->is_suspended_new = 1;
} elseif ($u->is_suspended === 'no') {
$u->is_suspended_new = 0;
}
$u->save();
}
}
Schema::table('users', function(Blueprint $table)
{
// 3- delete the old column
$table->dropColumn('is_suspended');
});
Schema::table('users', function(Blueprint $table)
{
// 4- rename the new column to match name of the deleted column
$table->renameColumn('is_suspended_new', 'is_suspended');
});
}
The down() method:
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
// IMPORTANT NOTE:
// because renaming (enum) column types is not supported in laravel 4.2 (as mentioned here https://laravel.com/docs/4.2/schema#renaming-columns)
// so we will make some changes in the order of the steps as follows:
//
// do the following steps in order:
// 1- rename the exiting column
// 2- add a new column with the desired data type and give it a name matches name of the existing column before renaming
// 3- fill the new column with the appropriate data
// 4- delete the old column
Schema::table('users', function(Blueprint $table)
{
// 1- rename the existing column
$table->renameColumn('is_suspended', 'is_suspended_old');
});
Schema::table('users', function(Blueprint $table)
{
// 2- add a new column with the desired data type to the table
// and give it a name matches name of the existing column before renaming
// note that after() method is used to order the column and works only with MySQL
$table->enum('is_suspended', ['yes', 'no'])->default('no')->after('is_suspended_old');
});
// 3- fill the new column with the approprite data
// note that you may need to use data in the old column as a guide (like in this example)
$users = User::all();
if ($users) {
foreach ($users as $user) {
$u = User::find($user->id);
if ($u->is_suspended_old == 1) {
$u->is_suspended = 'yes';
} elseif ($u->is_suspended_old == 0) {
$u->is_suspended = 'no';
}
$u->save();
}
}
Schema::table('users', function(Blueprint $table)
{
// 4- delete the old column
$table->dropColumn('is_suspended_old');
});
}

Categories