Mythriel
Mythriel

Reputation: 1380

Data mapper and zend framework

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

Answers (2)

Keyne Viana
Keyne Viana

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)


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;    
    }

Upvotes: 2

Mathieu Dumoulin
Mathieu Dumoulin

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

Related Questions