4

I have three tables,

Business:
  id
  name
Office:
  id
  name
  business_id
Employee:
  id
  name
  office_id

Employee's have office_id as a foreign key and Offices have business_id as a foreign key.

I have a domain object/entity that relates to each and a database mapper object that relates to each.

Now how to insert a new Employee when I am provided by a Business name, Office name and Employee name?

Initially I figure the logic should be something like:

$businessMapper = new businessMapper();  
$business = $businessMapper->findBusinessByName($business_name);

if ($business == false) {   
     $business = new businessEntity(array(         
                     'businessName' => $business_name,            
                   ));        
     $businessMapper->save($business);   
  } 

 $officeMapper = new officeMapper();     
 $office = $officeMapper->getOfficeByName($office_name, $business);

.......etc.......

But then I realised that if I have to save a new business there is no way that I have an office or an employee so it is a wasted query to try to get them. So then I thought I should create an if/else stucture.

get business entity by business_name  
if ($business == false) {
    create business entity
    save business entity
    create office entity
    save office entity
    create employee entity
    save employee entity
} else {
   get office entity by office_name + business_id

   if (office == false) {
     create office entity
     save office entity
     create employee entity
     save employee entity

   } else {

     ......etc......
   }

}

But there is so much duplicated logic and it is very unscaleable/dirty.

So how should it be achieved?

And secondly where should the logic go? Should it go in the mapper of employee? or the controller for the 'Add employee' action or should it have a new model?

I am using Zend as my framework, but I think the question applies to all MVC style structures so please feel free to respond regardless of your framework preference :)

Mark
  • 5,423
  • 11
  • 47
  • 62
  • 2
    It's a good question, but I don't believe it has anything to do with MVC. Also, it's more about data mappers than anything else. It's really nice to actually see a question where someone isn't hammering their app into some god-awful ORM anti-pattern. So +1 for that. –  Jul 18 '12 at 16:05

1 Answers1

3

If you use OR statements during the if() block and put your query within the if statement then it will only get executed if the first part of the IF statement fails - ensuring you don't needlessly perform queries. Personally we do something similar but when we create a new domain we have a flag set in the domain new=1 and we check this instead, same methodology just removes the need for these dirty variables ;-)

$businessMapper = Factory::getMapper('business');

if (!$business = $businessMapper->findByName("Business Name"))
{
    $business = $businessMapper->create();
    $business->setName("Business Name");
    $businessMapper->save($business);

    $newBusiness = true;
}

$officeMapper = Factory::getMapper('office');

if (isset($newBusiness) || !$office = $officeMapper->findByName("Office Name"))
{
    $office = $officeMapper->create();
    $office->setName("Office Name");
    $office->setBusiness($business->getId());
    $officeMapper->save($office);

    $newOffice = true;
}

$employeeMapper = Factory::getMapper('employee');

if (isset($newOffice) || !$employee = $employeeMapper->findByName("Employee"))
{
    $employee = $employeeMapper->create();
    $employee->setName("Employee Name");
    $employee->setOffice($office->getId());

    $employeeMapper->save($employee);
}
ByteNudger
  • 1,545
  • 5
  • 29
  • 37
williamvicary
  • 805
  • 5
  • 20