2016-05-21 73 views
13

我想在我現有的表中添加的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文檔中,但我得到了這個錯誤:

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

如何通過控制器實時添加列?

+0

你嘗試過'$ table-> schema() - > addColumn('price','decimal') - > update();'?只是一個猜測,不知道有關遷移cakephp – arilia

+0

@arilia你可以參考一個文檔鏈接?我覺得你很接近。 – Karma

回答

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(最新 - 截至今天 - 6月2日'16)

如果您使用的是不同的數據庫適配器,將其更改爲從MysqlAdapter該adapater。

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.

1

如果你想新列添加到產品表e.g的「價格」,價格是一個「小數」你應該去你的項目,並在控制檯中這樣寫:

bin/cake bake migration AddPriceToProducts price:decimal 

可以如看到一個新的文件配置/遷移/ 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 
+1

謝謝Jacek BBudzyñski。在我的系統中,用戶可以根據用戶需要動態創建列。因此,當用戶想要添加多個列時,他不能執行此控制檯代碼。是否有任何代碼啓動遷移,然後添加列沒有控制檯的東西? –

+1

@JigarDhaduk你可以添加多列'bin /蛋糕烘烤遷移AddPriceAndDiscountAndSomeToProducts價格:小數折扣:整數一些:字符串',但我不知道如何做到無控制檯..對不起 –

+0

糾正了這個問題。 @JacekBBudzyñski,OP想問一下如何在飛行中做到這一點。 – Karma

1

遷移插件還支持Running Migrations in a non-shell environment

Since the release of version 1.2 of the migrations plugin, you can run migrations from a non-shell environment, directly from an app, by using the new Migrations class. This can be handy in case you are developing a plugin installer for a CMS for instance. The Migrations class allows you to run the following commands from the migrations shell: migrate , rollback , markMigrated , status and seed .

Each of these commands has a method defined in the Migrations class.

您可以準備一些自定義處理程序,它將接受來自用戶端的列數據並運行遷移。在這種情況下,它可能是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(); 
+0

$ tsg感謝您的回覆。但是,如何通過此代碼添加新列?你能舉個例子嗎? –

+1

這只是內容的複製粘貼 – Karma