-- remataklan <[email protected]> wrote (on Friday, 08 May 2009, 05:36 AM -0700): > I was trying to understand the quickstart guide on the ZF site. > > My question is about the model part. > First of all a little check to see if I understand the stuff. As I > understand Zend_Db_Table handles the stuff with database. The mapper maps > this to the model and the model handles everything about getting and setting > data. Is this correct?
That's how we setup the quick start, yes. It's using three patterns: * Domain Model (the Default_Model_Guestbook class) * Data Mapper (the Default_Model_GuestbookMapper class) * Table Data Gateway (the Default_Model_DbTable_Guestbook class) One slight difference to what you wrote: the domain model is an object that has properties and behavior. The data mapper maps those to a persistence layer (the database, in this case). > Now the question, is it me or in the end the data we passed to the > view is a little bit large. I mean the whole model object is passed to > the final view. Is this the correct way to do it? It's one way to do it. When it comes down to it, the size of an item passed to the view is not really an issue -- and, in fact, passing objects is typically less expensive than other data as the objects are passed by reference. > And finally if I wanted to find to all posts from a certain user do I > need a new function in the mapper? Something like So, another person responded already, and he was suggesting using Zend_Db_Table as your model. This is a perfectly valid approach -- Martin Fowler notes in his section on Domain Models that it's often expedient to use ActiveRecord or table data gateway directly as your models, particularly for prototyping or when the model has a basically 1:1 mapping to the database. Problems arise, however, when you decide you want to persist your data differently. For instance, if you decide to move to a document storage system, or offload the direct data access to a middle-ware tier accessed via web services, or even want to abstract access so that you can use memcached unless the data is not cached. It was for these reasons that we chose to go with a slightly more abstract approach in the current iteration of the Quick Start. So, back to your example; that's one way to do it. The drawback is you'll find yourself writing methods in your mapper for every behaviour in your model, which quickly eliminates some of the benefits of having a data mapper in the first place. Another approach is to build and use a Query Object (http://www.martinfowler.com/eaaCatalog/queryObject.html), and then have the data mapper figure out how to map the query object into a request for the data access layer. In such a case, you might do something like this: public function query(Model_QueryObject $query) { $table = $this->getDbTable(); $select = $table->select(); foreach ($query->getCriteria() as $criteria) { $method = 'where'; if ($criteria->isOr()) { $method = 'orWhere'; } $statement = $criteria->getField() . ' ' . $criteria->getOperator() . ' ?'; $select->$method($statement, $criteria->getValue()); } $resultSet = $table->fetchAll($select); $entries = array(); foreach ($resultSet as $row) { $entry = new Model_List($row->toArray()); $entry->setMapper($this); $entries[] = $entry; } return $entries; } This affords you the ability to have a fairly generic data mapper that can handle arbitrary criteria. It's not quite as flexible as Zend_Db_Select (no support for joins, order, having, etc.), but for most purposes it would be adequate. Your model, then, would have a postsByUser() method, and would look something like this: public function postsByUser($userId) { $query = new Model_QueryObject(); $query->addCriteria(array( 'field' => 'user_id', 'operator' => '=', 'value' => $userId, )); return $this->getMapper()->query($query); } I won't go into the query object definition for now -- but it's basically just able to add criteria objects and return them. The criteria objects themselves simply are value objects, with properties for field, operator, and value. > public function postsByUser($userId) > { > $resultSet = > $this->getDbTable()->fetchAll($this->getDbTable()->select()->where('user_id > = ?', $userId)); > > $entries = array(); > foreach ($resultSet as $row) { > $entry = new Model_List(); > $entry->setId($row->id) > ->setEmail($row->email) > ->setComment($row->comment) > ->setCreated($row->created) > ->setMapper($this); > > $entries[] = $entry; > } > return $entries; > } > > or is there better way. > > > -- > View this message in context: > http://www.nabble.com/Zend-Model-and-quickstart-tp23445168p23445168.html > Sent from the Zend Framework mailing list archive at Nabble.com. > -- Matthew Weier O'Phinney Project Lead | [email protected] Zend Framework | http://framework.zend.com/
