views:

368

answers:

2

I am new to zend. I have been asked to redevelop a website that was once written in plain PHP and put it into the zend framework.

I am having a lot of trouble with database relationships, I cant seem to get my head round defining and querying relationships.

I would like to find a Category. From that Category I would like to be able to find all the CategoryInfo associated with it, and be able to query/sort/limit that dataset.

Here are my models.

Categorys.php

<?php
  class Default_Model_Categorys extends Zend_Db_Table_Abstract
  {
      protected $_name = 'Categorys';
      protected $_primary = 'id';

      protected $_dependentTables = array('Default_Model_CategoryInfo');
 }
?>

CategoryInfo.php

<?php
class Default_Model_CategoryInfo extends Zend_Db_Table_Abstract
{
    protected $_name = 'Category_Info';
    protected $_primary = 'id';

    protected $_referenceMap = array(
        'Categorys' => array(
            'columns' => array('cat_id'),
            'refTableClass' => 'Default_Model_Categorys',
           'refColumns' => array('id')
        )
      );
}
?>

CategoryController.php

<?php
  class CategorysController extends Zend_Controller_Action
  {
      public function indexAction()
      {
        /*
          this should redirect to all games
        */
          return $this->_forward("index", "games");
      }

      public function categoryAction()
      {
          /*
            shows a specific category
          */
          $id = (int) $this->_request->getParam('id');
          $category = new Default_Model_Categorys();
          $this->view->category = $category->fetchRow(
              $category->select()->where('id = ?', $id)
          );

          $categoryInfo = $this->view->category->findDependentRowset('Default_Model_CategoryInfo');

      }
  }

Firstly... am I doing anything wrong?

Secondly... how do I go about querying the dependent rowset?

A: 

Everything looks correctly to me. You don't query a dependent rowset. It is a query itself and it returns a result set. Basically what it is doing is pulling all records related to the current row you are working with as defined by $_referenceMap. Once you execute findDependentRowset(), you can foreach over the results which will give you instances of *Zend_Db_Table_Row*. From there you can display the related data as needed.

Personally I don't use Zend_Db Relationships. It is much easier to just make a second model method to query what I need. Also, Zend_Db Relationships do not support where clauses, so just making a second query is much more flexible than relationships.

Mark
+2  A: 

First, if you're searching for a category by its primary key, it's simpler to use the find() method:

$id = (int) $this->_request->getParam('id');
$category = new Default_Model_Categorys();
$this->view->category = $category->find($id)->current();

Second, to restrict or sort dependent Category_Info rows, you can use a Zend_Db_Table_Select object as an optional parameter of findDependentRowset(). Here's an example:

$select = $category->select()->where("info_type = 'PRICE'")
                             ->order("info_date")
                             ->limit(3);
$categoryInfo = $this->view->category->findDependentRowset(
    'Default_Model_CategoryInfo', null, $select);

Notice you can use any table object to create that select object. Since the "FROM" clause for that select will be set by the findDependentRowset() method, you just add other clauses and then pass it in.

PS: You don't need to declare $_dependentTables at all, unless you're going to use cascading update or cascading delete via PHP code. I recommend strongly against doing that -- it's far more efficient to let the RDBMS handle those cascading operations.

Likewise you should never have to declare $_primary if your database tables actually declare primary key constraints. Zend_Db_Table_Abstract knows how to inspect metadata to get the primary key column(s).

Bill Karwin
Bill you a hero. I thank you! Problem solved.
sfusion
Glad to help! I have edited the above to add the call the `current()` because `find()` always returns a rowset, not a single row.
Bill Karwin