Подтвердить что ты не робот

Динамически добавлять столбцы в существующую таблицу на лету в CakePHP 3

Я хочу добавить столбец в существующую таблицу в CakePHP 3.

Мой ContactsTable.php код файла:

<?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();

    }
}

Я пробовал, как описано в документации CakePHP 3, но я получил эту ошибку:

Вызов функции-члена addColumn() для не-объекта

Как добавить столбцы "на лету" через контроллер?

4b9b3361

Ответ 1

код:

<?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();
    }
}

После нескольких часов Hacking, наконец, нашел способ сделать это на лету.

Протестировано по умолчанию cakephp 3 (последнее - на сегодняшний день - 2 июня '16)

Если вы используете другой адаптер базы данных, измените его на этот адаптатор из MysqlAdapter.

Примечание для пользователей:

  • Это уродливый взлом, и его следует использовать ТОЛЬКО, если вы не работаете в организация, в которой для каждой фиксации миграции требуется одноранговая ссылка.

  • mt_rand() НЕ ДОЛЖЕН использоваться в качестве взлома номера версии.

  • нет канонического способа делать это через контроллеры. Обновление в источнике данных ДОЛЖНО всегда быть изменено посредством миграции - с использованием надлежащей структуры.

  • Обратитесь к Запуск миграции в среде без оболочки и попытайтесь создать журналы миграции в /config/migrations, что было бы больше правил, на лету, и у вас также будут журналы для просмотра сверстниками.

Ответ 2

Если вы хотите добавить новый столбец в таблицу продуктов, например, "цена", а цена - "десятичная", вы должны пойти в свой проект и записать это в консоли:

bin/cake bake migration AddPriceToProducts price:decimal

Вы можете увидеть новый файл, например. Config/Перемещения/20160501190410_AddPriceToProducts.php

<?php
use Migrations\AbstractMigration;

class AddPriceToProducts extends AbstractMigration
{
    /**
     * Change Method.
     *
     * More information on this method is available here:
     * http://docs.phinx.org/en/latest/migrations.html#the-change-method
     * @return void
     */
    public function change()
    {
        $table = $this->table('products');
        $table->addColumn('price', 'decimal', [
            'default' => null,
            ...
            'null' => true,
        ]);
        $table->update();
    }
}

а затем просто запустите миграцию, чтобы добавить этот столбец в базу данных, напишите это в консоли:

bin/cake migrations migrate 

Ответ 3

Плагин миграции также поддерживает Выполнение миграции в среде без оболочки.

С момента выпуска версии 1.2 плагина миграции вы можете запускать миграции из среды без оболочки, непосредственно из приложения, с помощью нового класса Migrations. Это может быть удобно, если вы разрабатываете инсталлятор плагинов для CMS, например. Класс Migrations позволяет запускать следующие команды из оболочки миграции: migrate, rollback, markMigrated, status и seed.

Каждая из этих команд имеет метод, определенный в классе Migrations.

Вы можете подготовить какой-то пользовательский обработчик, который будет принимать данные столбца с пользовательской стороны и выполнить миграцию. В этом случае это может быть некоторая форма с входами name и type. Миграция будет применена к БД после формы с данными, которые будут отправлены.

Вот как это использовать:

use Migrations\Migrations;

$migrations = new Migrations();

// Will return an array of all migrations and their status
$status = $migrations->status();

// Will return true if success. If an error occurred, an exception will be thrown
$migrate = $migrations->migrate();

// Will return true if success. If an error occurred, an exception will be thrown
$rollback = $migrations->rollback();

// Will return true if success. If an error occurred, an exception will be thrown
$markMigrated = $migrations->markMigrated(20150804222900);

// Will return true if success. If an error occurred, an exception will be thrown
$seeded = $migrations->seed();