2010-03-12 2 views
3

Используя Zend Framework, я создал модель для вставки записи в базу данных. Мой вопрос, после $this->insert($data) как я могу переключить активную таблицу, чтобы я мог вставить запись в другую таблицу?Как изменить имя Zend_Db_Table в модели для вставки в несколько таблиц

Вот мой код до сих пор:

class Model_DbTable_Foo extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'foo'; 

    public function addFoo($params) 
    { 
    $data = array(
     'foo' => $params['foo'], 
    ); 
    $this->insert($data); 
    $foo_id = $this->getAdapter()->lastInsertId(); 

    $data2 = array(
     'bar' => $params['bar'] 
    ); 
    // I need to change the Db Table name here. 
    $this->insert($data2); 
    $bar_id = $this->getAdapter()->lastInsertId(); 
    } 
} 

ответ

6

Zend_Db_Table является Table Data Gateway. Это

действует как шлюз к таблице базы данных. Один экземпляр обрабатывает все строки в таблице.

Это означает, что у вас есть один класс за стол. Ваш Model_DbTable_Foo представляет таблицу Foo в вашей базе данных и только эту таблицу. Он не должен вставлять в другие таблицы. Для этого вы бы использовали другой класс таблицы. Самый чистый вариант - добавить еще один слой поверх TDG, который знает, как обрабатывать вставки в несколько таблиц, например.

class Model_Gateway_FooBar 
{ 
    protected $_tables; 

    public function __construct(Zend_Db_Table_Abstract $foo, 
           Zend_Db_Table_Abstract $bar) 
    { 
     $this->_tables['foo'] = $foo; 
     $this->_tables['bar'] = $bar; 
    } 

    public function addFoo($data) 
    { 
     $this->_tables['foo']->insert($data['foo']); 
     // yaddayaddayadda 
     $this->_tables['bar']->insert($data['bar']); 
    } 
} 

Однако, это ваше приложение, и вы можете решить не беспокоить и просто создать новый экземпляр другого класса в классе Foo и сделать вставку из там, например,

$otherTable = new Model_DbTable_Bar; 
$otherTable->insert($data); 

Другим вариантом было бы поместить логику в контроллер, но я не могу рекомендовать его, потому что это не входит в обязанности контроллера и, как правило controllers should be kept thin and models should be fat.

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

$this->_tables['foo']->getAdapter()->beginTransaction(); 

, а затем commit() или rollback() в зависимости от результата запроса.

Также обратите внимание, что с ZF1.9 вы также можете создавать экземпляры Zend_Db_Table без необходимости определять конкретный подкласс сначала, например.

$fooTable = new Zend_Db_Table('foo'); 

См. Главу Zend_Db_Table in the ZF Reference Guide.

+0

Отличный совет! Я забыл все о транзакциях, я определенно хочу их использовать. Благодаря! – jwhat

+0

Gordon, не могли бы вы объяснить, почему я хотел бы набирать cast $ foo и $ bar в конструкторе как Zend_Db_Table_Abstract вместо моих пользовательских Model_DbTable_Foo и Model_DbTable_Bar? – jwhat

+0

Просто примечание для всех, кто интересуется транзакциями MySQL: мне пришлось изменить свой тип БД из MyISAM в InnoDB для поддержки транзакций. – jwhat

1

Я думаю, что вы должны иметь другой Model_DbTable, Model_DbTable_Bar и называют это либо

внутренне:

class Model_DbTable_Foo ... { 
    public function addFooAndBar() { 
    ... 
    $bar = new Model_DbTable_Bar(); 
    $bar->insert($data2); 
    } 
} 

или внешне:

class ModelX ... { 
    public function addFoos() { 
    $foo = new Model_DbTable_Foo(); 
    $foo->insert($data); 
    $bar = new Model_DbTable_Bar(); 
    $bar->insert($data2); 
    } 
} 
+0

Уникальные классы для уникальных столов имеют смысл и чувствуют себя чище. Благодаря! – jwhat

0

Также вы можете использовать класс Zend_Db_Table. Что-то вроде этого:

$fooTbl = new Zend_Db_Table('foo'); 
$lastFooID = $fooTbl->insert($data2) 
        ->getAdapter() 
        ->lastInsertId(); 

 Смежные вопросы

  • Нет связанных вопросов^_^