Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

<?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 described in CakePHP 3 documentation but I got this error:

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

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

like image 957
Jigar Dhaduk Avatar asked May 21 '16 11:05

Jigar Dhaduk


1 Answers

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.

Note to the users:

  • This is an 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.

like image 53
Karma Avatar answered Oct 11 '22 06:10

Karma