I am implementing the Data Mapper design pattern in my Zend Framework web application, and everything goes well, I am really enjoying working with the data mapper in Zend and not applying only the Row Gateway pattern, but I am having a problem regarding my architecture. I am not sure how to reference and work with foreign key constraints in a OOP fashion with my data mapper.
So I am having my Model class, my DbTable class and my Mapper class. Should I put all the foreign keys relations in my DbTable class and in this way I can retrieve in my mapper using findDependentRowset()
function, or a better approach would be to instantiate the dependent class in my mapper. What is the best OOP practice in mapping foreign keys using the Data Mapper pattern?

- 5,753
- 72
- 57
- 129

- 1,360
- 5
- 24
- 45
-
If you have lots of Impedance Mismatch, consider using an ORM, like Doctrine2. – Gordon Oct 01 '11 at 11:17
-
I already started the project with the data mapper implementation, only problem I am having is handling foreign key mapping if either to instantiate objects or to let the DbTable be aware of the database schema – Mythriel Oct 01 '11 at 11:43
-
My implementation is something like this: Model - same as what you said, but without any functions, only setters and getter for accessing Model properties DbTable - no functions here, only subclassing Zend_Db_Table_Abstract and providing the id and name for the table DataMapper - does the meat - here I have all the functions and i retrieve the DbTable class and set the properties with the Model class I want my system to be as loose coupled as it can, so the problem is my foreign key relations in my application – Mythriel Oct 01 '11 at 11:49
2 Answers
I'd go for the DataMapper as the other two shoudln't be aware of the ID per se althought it's always necessary for the relationship callers.
Model
- Property accessors and private property data holders
- Functions regarding correct usage of model
- Relatioship callers (calls relationship fetches in the DbTable to get parents or children rows)or returns cached data
DbTable
- Provides all static functions used to query data and instanciate the related Models such as :getById, getByName, getByComplexSearch, etc
- Provides all static relationship loaders such as: getParents, getChildrens and any other version you need
DataMapper
- Does the real meat and provides the getObjects method which accepts either a query part or a full query and loads the data into the ModelObjects and reads it back into a update, insert, delete query when needed
- Datamapper should be in charge of checking for relationship faults when inserting, updating or deleting using transactions if in InnoDB.
Does that make any sense?

- 12,126
- 7
- 43
- 71
I used to have findDependentRowset
on my systems. But not anymore! It's a waste of resources in most cases. Table joins should be on your SQL statement.
See my answer here: Hand made queries vs findDependentRowset
I'm still far away from use Doctrine or Propel (I've never needed it). Maybe some day. (Now using Doctrine 2. So... I suggest you the same now)
OLD ANSWER
After a couple of years working with Zend Framework, I come across with the following architecture:
1) I have an abstract mapper which all my mappers extends: Zf_Model_DbTable_Mapper
2) I have an abstract model (domain object) too, similar to the Row Data Gateway, with the exception that it is not a gateway. It's a generic domain object: Zf_Model
3) When populating object graphs (SQL joins) one mapper delegates to the other mappers that are responsible for the given object.
Example
This method is from the abstract mapper:
public function getById($id)
{
$tableGateway = $this->getTable();
$row = $tableGateway->fetchRow('id =' . (int) $id);
if (!$row)
retur null;
$row = $row->toArray();
$objectName = $this->getDomainObjectName();
$object = new $objectName($row['id']);
$object->populate($row);
return $object;
}

- 1
- 1

- 6,194
- 2
- 24
- 55