Reputation: 1380
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?
Upvotes: 3
Views: 2576
Reputation: 6202
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)
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;
}
Upvotes: 2
Reputation: 12244
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?
Upvotes: 4