2016-05-21 18 views
13

I Spalte in meiner vorhandenen Tabelle hinzufügen möchten hinzufügen, in CakePHP 3.Dynamische Spalten in einer vorhandenen Tabelle on the fly in CakePHP 3

Meine ContactsTable.php Datei 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(); 

    } 
} 

ich versucht habe, wie beschrieben in CakePHP 3-Dokumentation aber habe ich diesen Fehler:

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

Wie füge ich Spalten on-the-fly über den Controller?

+0

haben Sie versucht $ table-> schema() -> addColumn ('price', 'decimal') -> update(); '? Nur eine Vermutung, weiß nicht viel über Migration in CakePHP – arilia

+0

@arilia Kannst du mit einem Dokument Link verweisen? Ich denke du bist nah dran. – Karma

Antwort

6

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

Nach wenigen Stunden von Hacking, endlich einen Weg, es on-the-fly zu tun gefunden.

in Standard cakephp 3 (neueste - Stand heute - 2. Juni '16) Geprüft

Wenn Sie eine andere Datenbank-Adapter verwenden, ist es von MysqlAdapter zu diesem adapater ändern.

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

Wenn Sie neue Spalte Produkttabelle hinzufügen beispiel ‚Preis‘ und der Preis ist ein ‚dezimal‘ sollten Sie mit Ihrem Projekt gehen und schreiben diese in der Konsole:

bin/cake bake migration AddPriceToProducts price:decimal 

Sie können eine neue Datei, zum Beispiel 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(); 
    } 
} 

und später nur Migrationen starten diese Spalte Datenbank hinzuzufügen, schreiben Sie diese in der Konsole:

bin/cake migrations migrate 
+1

Danke Jacek B Budzyñski. In meinem System kann der Benutzer die Spalte dynamisch so erstellen, wie es der Benutzer möchte. Wenn der Benutzer mehr als eine Spalte hinzufügen möchte, kann er diesen Konsolencode nicht ausführen. Gibt es irgendeinen Code, der die Migration startet und dann eine Spalte ohne diese Konsoleninhalte hinzufügt? –

+1

@JigarDhaduk können Sie mehrere Spalte hinzufügen 'bin/Kuchen Bake Migration AddPriceAndDiscountAndSomeToProducts Preis: Dezimal Rabatt: Integer einige: String', aber ich weiß nicht, wie es ohne Konsole zu tun .. Entschuldigung –

+0

Korrigiert die Frage. @ JacekBBudzyñski, OP möchte fragen, wie man es im laufenden Betrieb macht. – Karma

1

Migration Plugin unterstützen Running Migrations in a non-shell environment auch.

Sie können einige benutzerdefinierte Handler vorbereiten, die Spaltendaten von der Benutzerseite akzeptieren und die Migration ausführen. In diesem Fall könnte es ein Formular mit name und type Eingaben sein. Die Migration wird auf die Datenbank angewendet, nachdem das Formular mit den Daten gesendet wurde.

Hier ist, wie es zu benutzen:

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 Danke für die Antwort. Aber wie kann ich mit diesem Code eine neue Spalte hinzufügen? Willst du bitte ein Beispiel geben? –

+1

Dies ist einfach eine Kopie einfügen des Inhalts – Karma