I asked a similar question a while back: Using the Data Mapper Pattern, Should the Entities (Domain Objects) know about the Mapper? However, it was generic and I'm really interested in how to accomplish a few things with Doctrine2 specifically.
Here's a simple example model: Each Thing can have a Vote from a User, a User may cast more than one Vote but only the last Vote counts. Because other data (Msssage, etc) is related to the Vote, when the second Vote is placed the original Vote can't just be updated, it needs to be replaced.
Currently Thing has this function:
public function addVote($vote)
{
$vote->entity = $this;
}
And Vote takes care of setting up the relationship:
public function setThing(Model_Thing $thing)
{
$this->thing = $thing;
$thing->votes[] = $this;
}
It seems to me that ensuring a User only has the last Vote counted is something the Thing should ensure, and not some service layer.
So to keep that in the Model, the new Thing function:
public function addVote($vote)
{
foreach($this->votes as $v){
if($v->user === $vote->user){
//remove vote
}
}
$vote->entity = $this;
}
So how do I remove the Vote from within the Domain Model? Should I relax Vote::setThing() to accept a NULL? Should I involve some kind of service layer that Thing can use to remove the vote? Once the votes start accumulating, that foreach is going to be slow - should a service layer be used to allow Thing to search for a Vote without having to load the entire collection?
I'm definitely leaning toward using a light service layer; however, is there a better way to handle this type of thing with Doctrine2, or am I heading in the right direction?