2016-05-21 42 views
13

chcę dodać kolumnę w mojej istniejącej tabeli w CakePHP 3.Dynamicznie dodać kolumny w istniejącej tabeli w locie w CakePHP 3

Mój kod ContactsTable.php file:

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

    } 
} 

Próbowałem jak opisano w dokumentacji CakePHP 3, ale mam ten błąd:

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

Jak dodać kolumny w locie za pomocą kontrolera?

+0

Czy wypróbowałeś '$ table-> schema() -> addColumn ('price', 'decimal') -> update();'? Tylko przypuszczenie, nie wiem zbyt wiele na temat migracji w cakephp – arilia

+0

@arilia Czy możesz odwołać się do linku do dokumentu? Myślę, że jesteś blisko. – Karma

Odpowiedz

6

Kod:

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

Po kilku godzinach Hacking, wreszcie znalazł sposób, aby to zrobić on-the-fly.

Testowany w domyślnej CakePHP 3 (ostatni - na dzień dzisiejszy - 2 czerwca '16)

Jeśli używasz innego adaptera bazy danych, zmień go na tym adapater od 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.

1

Jeśli chcesz dodać nową kolumnę do tabeli produktów np „cena”, a cena jest „dziesiętny” należy udać się do swojego projektu i napisać to w konsoli:

bin/cake bake migration AddPriceToProducts price:decimal 

można zobaczyć nowy plik np Config/Migracje/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(); 
    } 
} 

a później po prostu uruchomić migracje, aby dodać tę kolumnę do bazy danych, napisz to w konsoli:

bin/cake migrations migrate 
+1

Podziękowania dla Jacka B Budzyńskiego. W moim systemie użytkownik może dynamicznie tworzyć kolumnę jako pożądaną przez użytkownika. Więc jeśli użytkownik chce dodać więcej niż jedną kolumnę, nie może wykonać tego kodu konsoli. Czy istnieje kod uruchamiający Migration, a następnie dodawanie kolumny bez tej konsoli? –

+1

@JigarDhaduk możesz dodać wiele kolumn 'bin/cake bake migration AddPriceAndDiscountAndSomeToProducts cena: dziesiętna zniżka: całkowita część: string' ale nie wiem jak to zrobić bez konsoli .. przepraszam –

+0

Poprawiono pytanie. @ JacekBBudzyński, OP chce zapytać o to, jak to zrobić "w locie". – Karma

1

Wtyczka migracji również wspierać Running Migrations in a non-shell environment.

Można przygotować niestandardową procedurę obsługi, która będzie akceptować dane kolumn od strony użytkownika i przeprowadzać migrację. W takim przypadku może to być jakaś forma z wejściami name i type. Migracja zostanie zastosowana do DB po formularzu z danymi zostaną przesłane.

Oto jak go używać:

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 Dzięki za odpowiedź. Ale w jaki sposób mogę dodać nową kolumnę za pomocą tego kodu? Czy podam przykład? –

+1

To jest po prostu kopia zawartości – Karma