Hi all,
I need to export records from a child entity (say Product) including all parent records (say Category), and coming from a java background with a full blown ORM (Hibernate), I was wondering how to do that.
AFAIK, the DataObject::get method does not include all fields of the parent relations but can only filter on a parent. Here's a way to retrieve all those records including all parents, where I "only" need one sql query for all children, and one per parent relationship.
The intention is to make use of the dataobject model, so I wanted all records to be "converted" to DataObject instances before serializing them to the export (in JSON).
Is this ok or is there a better, shorter or more reliable way in SilverStripe?
Best regards,
Ronald
$childDataObjSet = DataObject::get($this->entityName, '', 'ID ASC');
// If there are any records, process them
if($childDataObjSet) {
// We need the first instance to find all parent relationships,
// ie all relationships defined for this entity as has_one
$firstRecord = $childDataObjSet->First();
$listOfParents = $firstRecord->has_one();
// Create an index with per parent entity all ID's
$parents = array();
foreach($listOfParents as $parentName => $key) {
$fieldName = $parentName.'ID';
foreach ($childDataObjSet as $record) {
$parents[$parentName][] = $record->getField($fieldName);
}
}
// Load all parents
foreach($parents as $parentName => $key) {
// Fetch all parents with a WHERE IN (...) database query
$parentObjDataSet = DataObject::get($parentName, $parentName.'.ID in ('.join(',',$parents[$parentName]).')');
// Create an array index where the key is the parent ID and the value is the parent record
$parentIndex = array();
foreach ($parentObjDataSet as $key => $parentRecord) {
$parentIndex[$parentRecord->ID] = $parentRecord;
}
// Loop through all children and assign the right parent record to each child
$parentIDFieldName = $parentName.'ID';
foreach ($childDataObjSet as $key => $child) {
$child->setComponent($parentName, $parentIndex[$child->$parentIDFieldName]);
}
}
// Now we have a $childDataObjSet with all parent entities neatly inserted in the DataObject's components property
}