Laravel 8 Migration - change enum values - laravel

I'm trying to change an enum value in database with Laravel migrations.
In first, i have tried this classic change :
Schema::table('questionnaires', function ($table) {
$table->enum('type', ['image', 'sound', 'video'])->nullable()->default('image')->change();
});
But I got the following error :
Unknown database type enum requested,
Doctrine\DBAL\Platforms\MySQL57Platform may not support it
I solved my problem by doing SQL directly :
DB::statement("ALTER TABLE questionnaires MODIFY COLUMN type ENUM('image', 'sound', 'video') DEFAULT 'image'");
But it does not seem optimal to me...
Is there a solution more in "agreement" with Laravel 8,
without going through pure SQL?
Thanks

Explanation
To elaborate a little bit more on this subject.
As noted here ENUMs cannot be reverse engineered into a certain type. Each ENUM is a value of it's own. Hence, you must specifically say to Laravel which type the ENUMs are.
This seems to be an issue with all versions of Laravel
In documentation for each version, i.e. https://laravel.com/docs/8.x/migrations#renaming-columns, you can find that changing enum fields is not supported. As noted here the DB statement inside your migration is the best workaround for now.
DB::statement("ALTER TABLE questionnaires MODIFY COLUMN type ENUM('image', 'sound', 'video') DEFAULT 'image'");
Migration files fix
This option is the above commented GitHub link which advises you to put this line of code before the actual migration inside up() method of migration file.
DB::connection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Models/enum types fix
I think this one is a lot less straightforward then the above mentioned, but still exists as a valid option, so I will put it here,
You can read an official doctrine-project website page here which shows you how to this thing from within models / enum types.

Related

Can this block of code of mine can be improved

[This is to populate data from two tables that one has two foreign keys from the same column as reference on the other table]
https://i.stack.imgur.com/D8fiv.png
[This is my schema for the table with the foreign key]
https://i.stack.imgur.com/eYDL0.png
This is written in laravel and it is working however i have an itchy feeling that this is wrong
As someone else has commented, you should put the code in your question. More context might also be necessary as it's not clear what you are trying to return from your view(). Are you returning $citizen, $family, or both? It would also be helpful to include what version of Laravel you are using. I'll assume you are using the latest Laravel 8.
Your code should work but you are making more work for yourself if you don't utilize Laravel's relationships. If you do, all the query stuff you have in your code can be reduced to just a few short lines of code such as this:
public function view(Citizen $citizen)
{
$citizen->load('family');
return $citizen;
}
Database Migration
You can shorten your migration by using foreignId(). See docs for details
https://laravel.com/docs/8.x/migrations#foreign-key-constraints
Before:
$table->integer('client_id')->unsigned();
$table->foreign('client_id')->references('id')->on('citizens');
After:
$table->foreignId('client_id')->constrained();
Route Model Binding
I'm assuming your view() method is in your controller and is called from a route. Since the one parameter required is the client's id, you can use Route Model Binding and skip fetching the client from the database.
https://laravel.com/docs/8.x/routing#route-model-binding
public function view(Citizen $citizen)
{
// your code
}
Relationships
You seem to have relationships set up but you aren't using them to load data. You should be able to load the related objects without any manual queries.
If you have a belongsTo(One to Many) relationship on the Citizen model to the Family model, you can load it like this:
$citizen->load('family');
or just use it like this
$relationship = $citizen->family->relationship;
I don't know what the relationships between your models are but you should read up on the different relationship types in the docs.
https://laravel.com/docs/8.x/eloquent-relationships

Laravel Migration - Data type also changes when renaming column

I want to rename the column in database using migration, but when i tried it, the datatype also changes. How to rename column without changing the data type.
The current name of the column in the database is
payment_amount_cash and its type is double(10,2)
I tried
$table->renameColumn('payment_amount_cash', 'payment_amount_full')->comment('Advanced payment')->default("0.00");
to rename the column. Then after migration, the name was changed but the data type was also changed from double(10,2) to only double thus, making the default value change from 0.00 to 0.
I also tried to change the data type after the schema of renaming the column.
$table->renameColumn('payment_amount_cash', 'payment_amount_full')->comment('Advanced payment')->default("0.00");
$table->double('payment_amount_full', 10,2)->change();
but this one gives me error upon migration.
Doctrine\DBAL\DBALException : Unknown column type "double" requested.
Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType().
You can get a list of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap().
If this error occurs during database introspection then you might have forgotten to register all database types for a Doctrine Type.
Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMappedDatabaseTypes().
If the type name is empty you might have a problem with the cache or forgot some mapping information.
With this, I just want to know how to rename the column without affecting the data type. After migration, I would like to retain the data type of the column I just changed the name.
I learned that there is an issue in Schema regarding the enum and still in discussion until now.
I just used the other way to update the datatype of the column.
DB::statement('ALTER TABLE reservations MODIFY COLUMN payment_amount_full double(10,2)');
and this works for me. If there are other ways on how to do this, please let me know. Thanks.

Adding new enum type to the existing enum column in Laravel migration

I am developing a Laravel application. What I am trying to do now is that I am trying to add a new enum type to the existing enum column.
This is how enum column is created/ migrated in the first place.
$table->enum('type', [BlogType::IMAGE, BlogType::TEXT]);
Now I am trying to add a new enum type to that column creating a new migration like this.
Schema::table('blogs', function (Blueprint $table) {
$table->enum('type', [BlogType::IMAGE, BlogType::TEXT, BlogType::VIDEO])->change();
});
As you can see, I added a VIDEO blog type.
When I run the migration, I got the following error.
Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.
Then I came across this link, Laravel 5.1 Unknown database type enum requested.
I tried adding the following in the constructor of the migration class.
\Illuminate\Support\Facades\DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Then I got the following error when I run the migration.
Unknown column type "enum" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database introspection then you might have forgotten to register all database types for a Doctrine Type. Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMappedDatabaseTypes(). If the type name is empty you might have a problem with the cache or forgot some mapping information.
Now I am not renaming the column, I am just adding the new supported enum value. What would be the best solution and how can I do that, pelase?
For now, we have only one solution: RAW query
public function up()
{
DB::statement('
ALTER TABLE `blogs` CHANGE COLUMN `type` `type`
ENUM("'.implode([BlogType::IMAGE, BlogType::TEXT, BlogType::VIDEO], '", "').'")
NOT NULL
DEFAULT "'.BlogType::IMAGE.'"
');
}
Where blogs is table name and type column name.

PhpStorm suggest MySQL database column name

I am interested in how to do MySQL column name suggestion.
Here is my simple database.
This is my php code in route/web.php
This is my about.blade.php file
I want it to suggest me MySQL column name like id, body, created_as, update_at.. like this $task->... and here to suggest me all the column names which has table.
Is this possible?
Sort of.
However, you wouldn't be able to use the DB class, you'd need to create a Model and create the appropriate #property tags in the docblock.
Sometimes it works, sometimes it doesn't I have noticed. It really depends if PHPStorm picks up the proper context. It likely won't be picked up automatically in blade templates but you can type hint any variable:
/** #var TaskModel $task */
There is a good plugin for IDE autocompletion with regards to Laravel here: https://github.com/barryvdh/laravel-ide-helper

Adding new columns to an Existing Doctrine Model

First of all Hats of to StackOverflow for their great service and to you guys for taking your time to answer our questions.
I am using Doctrine ORM 1.2.4 with CodeIgniter 1.7.3. I created a Site with some required tables and pumped in with datas only to realize at a later point of time that a specific table needs to have one more column.
The way i created the tables was by writing the model as php classes which extend the Doctrine_Record.
Now i am wondering if i need to just add the column in the model that requires a new column in the setTableDefinition() method and recreate that table or is there any other way that easily does this. The former method i've mentioned requires me to drop the current table along with the datas and recreate the table which i do not wish. Since doctrine seems to be a very well architect-ed database framework, i believe it is lack of my knowledge but surely should exist a way to add new columns easily.
PS: I am not trying to alter a column with relations to other tables, but just add a new column which is not related to any other table. Also i create the tables in the database using Doctrine::createTablesFromModels(); When i alter a table with a new column and run this method it shows errors.
Since you don't want to drop & recreate, use a Doctrine Migration.
The official docs here show many examples:
http://www.doctrine-project.org/projects/orm/1.2/docs/manual/migrations/en
Since you just want to add a field, look at their second code example as being the most relevant which is like this:
// migrations/2_add_column.php
class AddColumn extends Doctrine_Migration_Base
{
public function up()
{
$this->addColumn('migration_test', 'field2', 'string');
}
public function down()
{
$this->removeColumn('migration_test', 'field2');
}
}

Resources