Jigar Dhaduk Jigar Dhaduk - 6 months ago 38
PHP Question

Dynamically add columns in an existing table on the fly in cakephp 3

I want to add column in my existing table in

cakephp 3
.

My
ContactsTable.php
file code is..

<?php

namespace App\Model\Table;

use Cake\ORM\Table;
use Migrations\AbstractMigration;

class ContactsTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Timestamp');

$table = $this->table('contacts');
$table->addColumn('price', 'decimal')->update();

}
}


I have tried as cakephp 3 documentation but I got error..

Call to a member function addColumn() on a non-object


How do I add columns on-the-fly via the controller?

Answer

Code:

<?php

namespace App\Controller;

use Cake\Core\Configure;
use Cake\Network\Exception\NotFoundException;
use Cake\View\Exception\MissingTemplateException;
use Cake\ORM\TableRegistry;
use Cake\Database\Schema\Table;
use Cake\Datasource\ConnectionManager;
use \Migrations\AbstractMigration as AbstractMigration;
use \Phinx\Db\Adapter\MysqlAdapter as MysqlAdapter;

class PagesController extends AppController
{
    public function display()
    {
        $connectionArray = ConnectionManager::get('default')->config();
        $connectionArray['pass'] = $connectionArray['password'];
        $connectionArray['user'] = $connectionArray['username'];
        $connectionArray['name'] = $connectionArray['database'];

        $migrationObject = new AbstractMigration(mt_rand());
        $migrationObject->setAdapter(new MysqlAdapter($connectionArray));
        $tree = $migrationObject->table('tests');


        $tree->addColumn('something', 'text')
                        ->update();
    }
}

After few hours of Hacking, finally found a way to do it on-the-fly.

Tested in default cakephp 3 (latest - as of today - 2nd June '16)

If you are using a different database adapter, change it to that adapater from MysqlAdapter.

This is Ugly hack and should be used ONLY if you do not work in an organization where each migration commit requires peer reference.

mt_rand() must NEVER be used as a version number hack.

There is no canonical way of doing it via the controllers. Update in a datasource MUST always be done modified via migrations - using a proper structure.

Refer to Running Migrations in a non-shell environment and try to create a migrations logs under /config/migrations, that would be more rule-specific-on-the-fly and you will also have logs for peers to review.