1

A follow-up to this question - assume I have a Project object, and am using a ProjectMapper object to handle Insert/Update/Delete, thus keeping the Project object from knowing about the database.

A Project can have several Forms associated with it, so when I am loading a page, after I've handled Project population, I need to fetch a list of the formIDs associated with the Project from the database so I can loop through it and create Form objects and populate them via a FormMapper object.

This is a simple enough function, but I'm not quite sure where I should put it. As it's talking to the database, it doesn't go in the Project or Form objects. It seems like it would go in the ProjectMapper object, but the retrieved data isn't going to be mapped to a Project - it's going to be used in mapping data to Forms.

A code-based representation of the above:

$project = new Entity\Project;
$projectMapper = new Mapper\Project($db);

$project->setId(43);
$projectMapper->load($project); //load() will take ID of passed object, fetch data from DB and call setter.

$formIDs = XXXX->getFormIDs($project); //Which object should replace the XXXX?
$formMapper = new Mapper\Form($db);

foreach ($formIDs as $num=>$id) {
    $form = new Entity\Form($id)
    $formMapper->load($form);
}

It almost feels like I'm overthinking it, but there's a niggling sense of 'wrongness' whenever I go to just put getFormIDs() in PPRMapper. Does it really matter where I put this method? Should I create a separate 'helper' class that handles things like this, despite their apparently controversial nature?

Community
  • 1
  • 1
Damien H
  • 174
  • 11

1 Answers1

0

Agreed -- it looks and feels wrong.

I do it like this: Entity\Project has a method called setForms. Through whatever mechanism your mapper's loading method populates Entity\Project, it also creates a new instance of Entity\FormCollection as a property of Entity\Project and calls that instance's setProject method:

In other words, your project mapper looks something like:

public function load( Entity\Project $project )
{
    // map data
    // populate $project through some method like $project->setParams( $data )
}

Then Entity\Project's setParams method:

public function setParams( $params )
{
    // call a bunch of $this->setters to populate instance

    // create a FormCollection:
    $forms = new Entity\FormCollection;
    $forms->setProject( $this )

    $this->setForms(  $forms );
}

To get the forms associated with the project, a FormCollection mapper does the work:

$project->setId( 43 );
$projectMapper->load( $project );

$formCollection = $project->getForms();

$formCollectionMapper = new Mapper\FormCollection( $db );
$formCollectionMapper->load( $formCollection );

// now all your populated form instances can be accessed individually:
// here I use a method `getAssoc()` but you can also create a custom iterator and
// drop the method call
foreach($formCollection->getAssoc() as $form)
{
    $form; // instance of Entity\Form
}

Read here for more information on the collection pattern. Also, maybe this post and/or this post will help guide.

Community
  • 1
  • 1
jeremy
  • 9,455
  • 4
  • 36
  • 57