views:

68

answers:

2

I know Domain Models and Data Mappers are the OOP snob's choice (using 'snob' in a complementary way, as Martin Fowler calls himself one) - however, even Fowler says in POEAA that

"Active Record is a good choice for domain logic that isn't too complex..."

I have a simple product and invoice domain model, not too many tables/objects/concepts to model, and the relationships aren't that overly complex. So, is this a good use case for Active Record?

Fowler also states that Active Record is similar to the Row Data Gateway, the difference being that Active Record has domain logic.

Assuming this is a valid use case for Active Record, and since Zend provides Row Data Gateway, a solution of intelligent (as opposed to simply adding the table name) extending those objects seems like a good way to create Active Record objects using the Zend Framework. Indeed, that concept is discussed in this SO answer. Is this an acceptable way of implementing Active Record inside the Zend Framework?

Of course the most popular answer to that question is one by Bill Karwin (who worked on Zend's Db implementation), recommending not using Zend_Db_Table or Zend_Db_Row this way (at least that's how I read it).

I fully accept wanting to move to a Data Mapper solution if the domain model in question becomes more complex. I've looked at various ORM/DataMappers (for more than just the domain model in question, been reading more about OOP design patterns lately), and they really seem too much for some things.

+3  A: 

I've done this and have been completely satisfied with the result.

IMO, the only thing you must never do is to use the parent methods in your controllers and views/view helpers. i.e. Always write your own methods in the extended Zend_Db_Table_Abstract and Zend_Db_Table_Abstract_Row classes that are used by the rest of your application. This will leave you option of swapping out your TDG/AR for something more complex if the need arises.

Rob Allen
Agree completely on not using the underlying data-access directly. What have you found that works? Full Data Mapper?
Tim Lytle
I rarely do complicated if I can avoid it :)For simple stuff, I will create `class News extends Zend_Db_Table_Abstract` and class `class NewsItem extends Zend_Db_Table_Row_Abstract`. I find setFromArray() is fine for populating a NewsItem and save() is okay too. I create new fetch methods in News.
Rob Allen
@Rob Allen - Wow, completely misread your first line - I threw in a 'never' before 'have been completely satisfied'. Hence the 'what have you found that works' after you already answered that. Thanks for the insight.
Tim Lytle
+1  A: 

For something simple, then yes models extending Zend_Db_Table package is a fine choice. I've used it many times with great success, and it looks something like this:

class App_Model_Users extends Mojito_Model_Abstract
{    
    protected $_dbTableClass='App_Model_Users_Table';

    public function getByEmail($email)
    {
        $Select=$this->_DbTable->select()->where(new Zend_Db_Expr('LOWER(usrEmail)=?'),strtolower($email));
        $User=$this->_DbTable->fetchRow($Select);
        return $this->verifyRow($User);
    }

}

class App_Model_Users_Table extends Zend_Db_Table_Abstract
{
    protected $_name = 'users';
    protected $_primary = 'user_id';
    protected $_rowsetClass = 'App_Model_Users_Rowset';
    protected $_rowClass = 'App_Model_Users_Row';
}

class App_Model_Users_Rowset extends Zend_Db_Table_Rowset_Abstract
{
}

class App_Model_Users_Row extends Zend_Db_Table_Row_Abstract
{
    protected function _insert()
    {
        // pre instert logic such as:
        $this->password = sha1($this->password);
    }

    protected function _postInsert()
    {
        // email user a welcome
    }

    protected function _postDelete()
    {
        // delete related files such as avatar
        // can also get a rowset of related many's to delete
    }

}

You can read more here http://talentedmrjones.posterous.com/simple-models-with-zenddbtable

Of course you might not need or want all the functionality that I'm extending from Mojito_Model_Abstract, but I'm sure you get the gist of what's happening.

talentedmrjones
@Tim sorry I totally misread your question! I see now that it is about whether to use ActiveRecord or TDG, not asking how to implement Zend_Db_Table which I'm sure you've already nailed.
talentedmrjones
@talented, no problem, your examples help validate what I was thinking. I appreciate it.
Tim Lytle