How to save an object when you do not know if its parent objects exist or not?
datamapper, model, model-view-controller, php, zend-framework
Solution
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);
}
Problem
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 :)