Pre-fill database table column field with HTML using Laravel migration - php

I have added a new column to a database table using Laravel migration as follows:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddFAQToStoreTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('store', function (Blueprint $table) {
$table->longText('FAQ')->after('description');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('store', function (Blueprint $table) {
$table->dropColumn('FAQ');
});
}
}
As a default value for FAQ, I want the following HTML pre-filled for all stores when I run the migration:
<div><span style="font-weight:600">Can we get our purchase delivered?</span><br/>
Yes, items purchased can be delivered. However, due to COVID-19 restrictions, we are expecting a 3-5 business days' delay.</div>
Is it possible to add a new column and simultaneously pre-populate it with a HTML block like above? If it's better practice to use database seeders, please advise as well. Thanks

You can update new column using Seeder and executing query.
1.Seeder - Link
2. executing query in your migration file
public function up()
{
Schema::table('store', function (Blueprint $table) {
$table->longText('FAQ')->after('description');
});
$html = '<div><span style="font-weight:600">Can we get our purchase delivered?</span><br/>
Yes, items purchased can be delivered. However, due to COVID-19 restrictions, we are expecting a 3-5 business days' delay.</div>';
DB::statement('UPDATE store SET FAQ='.$html);
}

I would recommend don't use this method, store a simple paragraph in your DB and add it to your blade template with the desired tag but If you insist and want to insert default data such as FAQ or other things, which don't have a specific structure, you should add them with Laravel Query Builder like below:
// define table
public function up()
{
Schema::table('store', function (Blueprint $table) {
$table->longText('FAQ')->after('description');
});
}
// insert some stuff
DB::table('store')->where('FAQ', '=', '')->update(array('FAQ' => '<div> . . . </div>'));
And use it in your blade template.

Related

How can I modify DB structure in Laravel without truncating tables?

I have defined a DB table structure below.
If I want to modify a table column:
From
$table->string('active',1);
To:
$table->string('active',1)->nullable(); // allow null values
Every time I run the migration script, my tables will be truncated.
Is there a way to define a table structure and have it be modified to correct structure WITHOUT dropping the table?
Here is my code for now:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class VTUser extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('Z_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('nickname')->unique();
$table->string('email')->unique();
$table->string('passhash');
$table->string('keygen');
$table->string('active',1)->nullable();
$table->string('banned',1);
$table->string('admin',1);
$table->string('step',1);
// $table->rememberToken();
// $table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('Z_user');
}
}
There can be two ways of achieving this -
Either you can rollback the migration with php artisan migrate:rollback --step=1 and then change the up function with $table->string('active',1)->nullable();
Create a new migration to update the table by doing $table->string('active',1)->nullable(); in this new migration.

How do I add default value as same from another column in Laravel Migration

I have a questions table in my database, in which I have a column of question_title, now I have added a column question_slug, which will contain the question's slug URL, so how I set question_slug default value as question_title in Laravel Migration, I need this all because I have questions saved in the database so I have run php artisan make:migration add_column_to_questions --table=questions now I have this code:
Schema::table('questions', function (Blueprint $table) {
$table->string('question_slug')->default();
});
first of all, create a new migration and put this code within it:
connections_string : it's within web/config/database.php file
configuration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class NameOfUrMigration extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('questions', function (Blueprint $table) {
$table->string('question_slug')->default();
});
$questions = DB::connection('connections_string')->table('questions')->get();
foreach($questions as $question)
{
$question->question_slug = str_slug($question->question_title);
$question->save();
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
}
}
According to the documentation, default() is used to Declare a default value for a column.
That means the value that gets inserted by default in a field if you do not provide a value for it in the insert query.
The default() cannot help you achieve what you need here.
What you could do is create a new migration class with a raw query in the up() method which will update the value of question_slug with the value of question_title.
something like this:
public function up()
{
$sql = "UPDATE `questions` SET `question_slug` = `question_title` WHERE 1;";
//add filtering conditions if you don't want ALL records updated
DB::connection()->getPdo()->exec($sql);
}
Make sure you also create a corresponding down() method for the rollback

Laravel Migrations onDelete Restrict not working

Hello I'm trying to define relationships in my migrations
I'm using on delete restrict to prevent deletion of parent record when child is present. but its not working. For example I have this event table (parent) that has editions (child). I'm using event_id in editions table
with onDelete('restrict') and have event_id in my edition table..
It should restrict me on deleting from events table as long record has child record in edition tables right? but its not..
Here are the migrations of both tables
Events (parent)
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateEventsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('events', function (Blueprint $table) {
//master table
$table->increments('event_id');
$table->string('name');
$table->text('full_name');
$table->text('description');
$table->tinyInteger('status');
$table->integer('created_by');
$table->integer('updated_by');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('events');
}
}
Editions (Child)
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateEditionsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('editions', function (Blueprint $table) {
$table->increments('edition_id');
$table->integer('event_id')->unsigned();
$table->string('name');
$table->dateTime('start')->nullable();
$table->dateTime('end')->nullable();
$table->enum('stage', ['Archived', 'Cancelled', 'Closed', 'Live', 'On-site', 'Pre-event', 'Sold out'])->nullable()->default('Pre-event');
$table->tinyInteger('status');
$table->integer('created_by');
$table->integer('updated_by');
$table->timestamps();
});
Schema::table('editions', function($table) {
$table->foreign('event_id')
->references('event_id')->on('events')
->onDelete('restrict')->onUpdate('restrict');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('editions');
}
}
According to this thread :
If you are using the SoftDeletes trait, then calling the delete()
method on your model will only update the deleted_at field in your
database, and the onDelete constraint will not be triggered, given
that it is triggered at the database level i.e. when a DELETE query is
executed.
So make sure that you use DELETE not SoftDeletes otherwise you can add the constraint manually.
One thing I see missing from your foreign key definition is adding an index on it, that is a requirement for foreign keys and it might be what's caussing issues for you.
Try changing
$table->integer('event_id')->unsigned();
to
$table->integer('event_id')->unsigned()->index();
Also, you can just add the foreign key definition immediately after the column definition, no need to put it in a different Schema::table() block.

PHPUnit doesn't seem to be running Laravel Migration

I've got an issue where I'm running some tests in laravel 5.4 via phpunit
I'm using an in memory sqlite database for testing
I've got a test class which i've removed bunch of other stuff from so it effectively looks like
<?php
namespace Tests\Unit;
use App\User;
use App\Order;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class OrderTest extends TestCase
{
use DatabaseMigrations;
/** #test */
function can_update_status()
{
// This is empty, it fails on this test because its alphabetically the first test in the whole suite.
}
}
I've recently created a new migration which adds the "paid" column
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddStatusToOrders extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('completed');
$table->boolean('paid')->default(0);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->boolean('completed')->default(0);
$table->dropColumn('paid');
});
}
}
However whenever I run this test I get an error saying the paid column doesn't exist - even after a composer du
PHPUnit 6.0.7 by Sebastian Bergmann and contributors.
...................................E
Time: 10.69 seconds, Memory: 46.00MB
There was 1 error:
1) Tests\Unit\OrderTest::can_mark_as_paid
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such column: paid (SQL: update "orders" set "paid" = 1, "updated_at" = 2017-04-05 15:27:11 where "id" = 1)
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:647
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Caused by
Doctrine\DBAL\Driver\PDOException: SQLSTATE[HY000]: General error: 1 no such column: paid
/Users/owen/Sites/1st-choice-spares/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:79
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:470
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:640
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Caused by
PDOException: SQLSTATE[HY000]: General error: 1 no such column: paid
/Users/owen/Sites/1st-choice-spares/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:77
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:470
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:640
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Does anybody have any ideas why this would be happening, and how I can resolve it? It might be worth adding I've tried changing the column names etc and the same issue is happening with that
Thanks
UPDATE
If I comment out the lines in the down migration e.g $table->dropColumn('paid');
Then it continues to run - however I'm struggling to understand why the down method would be running before the up has been run?
Update 2
It seems the above finding was due to the column not getting created in the first place, if i suppress that error, the original error appears that the column doesn't exist - which suggests the migration failed to create it.
According to laravel documentation
Dropping or modifying multiple columns within a single migration while using a SQLite database is not supported.
And although you not trying to modify or drop multiple columns ,you are trying to drop and create in one single migration and in both cases ALTER TABLE query is executed ,and the problem here is the limitations of ALTER TABLE query of sqlite .
You can separate each statement like this:
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('completed');
});
Schema::table('orders', function (Blueprint $table) {
$table->boolean('paid')->default(0);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->boolean('completed')->default(0);
});
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('paid');
});
}

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');

Categories