13

我想在 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()

如何通过控制器即时添加列?

4

3 回答 3

6

代码:

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

经过几个小时的黑客攻击,终于找到了一种即时进行的方法。

在默认 cakephp 3 中测试(最新 - 截至今天 - 16 年 6 月 2 日)

如果您使用的是不同的数据库适配器,请将其更改为 MysqlAdapter 中的该适配器。

用户注意:

  • 这是一个丑陋的 hack,仅当您不在每个迁移提交都需要同行参考的组织中工作时才应使用。

  • mt_rand() 绝不能用作版本号破解。

  • 没有通过控制器执行此操作的规范方法。必须始终通过迁移修改数据源中的更新 - 使用适当的结构。

  • 请参阅在非 shell 环境中运行迁移并尝试在 下创建迁移日志/config/migrations,这将更加特定于规则,并且您还将有日志供同行查看。

于 2016-06-02T08:03:54.827 回答
2

迁移插件还支持在非 shell 环境中运行迁移

自迁移插件版本发布以来1.2,您可以使用新的 Migrations 类直接从应用程序从非 shell 环境运行迁移。例如,如果您正在为 CMS 开发插件安装程序,这会很方便。Migrations 类允许您从迁移 shell 运行以下命令:migraterollbackmarkMigrated和.statusseed

这些命令中的每一个都有一个在 Migrations 类中定义的方法。

您可以准备一些自定义处理程序,它将接受来自用户端的列数据并运行迁移。在这种情况下,它可能是带有nametype输入的某种形式。提交带有数据的表单后,迁移将应用于数据库。

以下是如何使用它:

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();
于 2016-05-28T18:54:03.077 回答
1

如果您想在产品表中添加新列,例如“价格”并且价格是“十进制”,您应该转到您的项目并在控制台中写入:

bin/cake bake migration AddPriceToProducts price:decimal

您可以看到一个新文件,例如Config/Migrations/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 
于 2016-05-21T14:23:18.740 回答