Doctrine 1.2 NestedSet properties and relation inheritance from ancestors
I have a Doctrine 1.2 project that I'm refactoring in order to have a tree structure for a table using doctrine beahaviour NestedSet with multiple roots.
What I need is an inheritance (Not in the OO common sense) from ancestors to descendants in which the descendants inherits properties from the closest ancestor where their own properties are missing. Same thing would happen with relations.
Let me explain with an example:
开发者_如何学JAVACategory:
actAs:
NestedSet:
hasManyRoots: true
rootColumnName: root_id
columns:
name: string(50)
another_property: string(50)
active: boolean
Tag:
columns:
value: string(50)
CategoryTag:
columns:
category_id: integer
tag_id: integer
What I want to perform is:
- retrieve if a category is active, that means verifying if all the ancestors are active
- if another_property is missing for a given category, inherit it from closest ancestor in which is present
- retrieve tags for a given category; if tags are missing, retrieve them from the closest ancestor
What would you suggest as best approach in order to maximize speed and flexibility?
Well, this is faily simple. Just get the tree with relations that you need like this:
class ModelTable extends Doctrine_Table
{
/**
* Gets tree element in one query
*/
public function getModelTree()
{
$q = $this->createQuery('g')
->leftJoin('g.Tags t')
->orderBy('g.root_id')
->addOrderBy('g.lft')
->where('g.root_id NOT NULL')
;
return $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY_HIERARCHY);
}
}
Then, you can render it like this:
<?php function echoNode($tree, $parent=null) { ?>
<ul>
<?php foreach ($tree as $node): ?>
<li data-property='<?php echo false != $node['property'] ? $node['property'] : $parent['property'] ?>'>
<?php echo $node['name'] ?>
<?php if (count($node['__children']) > 0): ?>
<?php echo echoNode($node['__children'], $node) ?>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php } ?>
<?php echo echoNode($tree) ?>
Notice, how you can get 'property' from parent node, if it absent. Another way to address this issue is to use Doctrine_Core::HYDRATE_RECORD_HIERARCHY. This allows use to call methods on $nodes when looping. You can create a Model::getClosestProperty() method, for example, to get the property from closest parent. But, this is not as efficient as array hydration.
精彩评论