Как изменить имя Zend_Db_Table в модели для вставки в несколько таблиц - PullRequest
3 голосов
/ 13 марта 2010

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

Вот мой код:

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

Ответы [ 3 ]

6 голосов
/ 13 марта 2010

Zend_Db_Table является шлюзом табличных данных . Он

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

Это означает, что у вас есть один класс на таблицу. Ваш 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);

Другим вариантом было бы поместить логику в контроллер, но я не могу рекомендовать это, потому что это не входит в обязанности контроллера, и, как правило, контроллеры должны быть тонкими, а модели должны быть толстыми .

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

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

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

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

$fooTable = new Zend_Db_Table('foo');

См. Главу Zend_Db_Table в Справочном руководстве ZF .

1 голос
/ 13 марта 2010

Я думаю, у вас должен быть другой 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 голосов
/ 03 октября 2012

Также вы можете использовать класс Zend_Db_Table . Примерно так:

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