Let's assume the following tables setup for a Zend Framework app.
user (id)
groups (id)
groups_users (id, user_id, group_id, join_date)
I took the Data Mapper approach to models which basically gives me:
- Model_User, Model_UsersMapper, Model_DbTable_Users
- Model_Group, Model_GroupsMapper, Model_DbTable_Groups
- Model_GroupUser, Model_GroupsUsersMapper, Model_DbTable_GroupsUsers (for holding the relationships which can be seen as aentities; notice the "join_date" property)
I'm defining the _referenceMap in Model_DbTable_GroupsUsers:
protected $_referenceMap = array (
'User' => array (
'columns' => array('user_id'),
'refTableClass' => 'Model_DbTable_Users',
'refColumns' => array('id')
),
'App' => array (
'columns' => array('group_id'),
'refTableClass' => 'Model_DbTable_Groups',
'refColumns' => array('id')
)
);
I'm having these design problems in mind:
1) The Model_Group only mirrors the fields in the groups table. How can I return a collection of groups a user is a member of and also the date the user joined that group for every group? If I just added the property to the domain object, then I'd have to let the group mapper know about it, wouldn't I?
2) Let's say I need to fetch the groups a user belongs to. Where should I put this logic? Model_UsersMapper or Model_GroupsUsersMapper?
I also want to make use of the referencing map (dependent tables) mechanism and probably use findManyToManyRowset or findDependentRowset, something like:
$result = $this->getDbTable()->find($userId);
$row = $result->current();
$groups = $row->findManyToManyRowset(
'Model_DbTable_Groups',
'Model_DbTable_GroupsUsers'
);
This would produce two queries when I could have just written it in a single query. I will place this in the Model_GroupsUsersMapper class.
An enhancement would be to add a getGroups method to the Model_User domain object which lazily loads the groups when needed by calling the appropriate method in the data mapper, which begs for the second question. Should I allow the domain object know about the data mapper?