tif*_*ang 6 php mysql recursion laravel-4
所以我的数据结构如下:
id|parent_id|name
1 |null |foo
2 |1 |bar
3 |2 |baz
Run Code Online (Sandbox Code Playgroud)
所以基本上foo->bar->baz.我很难理解如何使用laravel的查询构建器来获取子行的行,然后是它的祖先(直到parent_id == null).这可以用laravel完成吗?我已经完成了一些研究,Postgres RECURSIVE虽然MySQL没有(Postgres递归查询在遍历parent_id时更新字段的值).
我相信MySQL有类似的东西:如何在MySQL中进行递归SELECT查询?
但是我如何在Laravel中实现这个呢?
我的开始代码基本上是使用查询范围,但我只是没有做到正确:
Model::select('name')->getParent(3); //get baz and the ancestors of baz
protected function scopeGetParent($id) {
$parent = Model::where('id', '=', $id);
return $query->getParent($parent->parent_id);
}
Run Code Online (Sandbox Code Playgroud)
我想要的结果是:
name
baz
bar
foo
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
所以在摆弄merge()了Collections类的方法之后:
public static function ancestors($id)
{
$ancestors = Model::where('id', '=', $id)->get();
while ($ancestors->last()->parent_id !== null)
{
$parent = Model::where('id', '=', $ancestors->last()->parent_id)->get();
$ancestors = $ancestors->merge($parent);
}
return $ancestors;
}
Run Code Online (Sandbox Code Playgroud)
这将产生我需要的东西,但我相信它可以更清洁,所以请随意编辑它!
我修改了tiffanyhwang解决方案,并将其转变为非静态方法,并包含一个属性访问器,以使其更易于获得结果。
public function ancestors()
{
$ancestors = $this->where('id', '=', $this->parent_id)->get();
while ($ancestors->last() && $ancestors->last()->parent_id !== null)
{
$parent = $this->where('id', '=', $ancestors->last()->parent_id)->get();
$ancestors = $ancestors->merge($parent);
}
return $ancestors;
}
Run Code Online (Sandbox Code Playgroud)
和访问器,从模型属性中检索祖先的集合
public function getAncestorsAttribute()
{
return $this->ancestors();
// or like this, if you want it the other way around
// return $this->ancestors()->reverse();
}
Run Code Online (Sandbox Code Playgroud)
所以现在您可以得到像这样的祖先:
$ancestors = $model->ancestors;
Run Code Online (Sandbox Code Playgroud)
并且由于它是一个Collection,因此您现在可以轻松地执行以下操作:
echo $model->ancestors->implode('title',', ');
Run Code Online (Sandbox Code Playgroud)
小智 4
另一种方法是使用etrepat/baum包,它是Nested set model的 Laravel 实现。它使用更快的有序树并使用非递归查询。虽然您的数据结构如下:
root
|_ Child 1
|_ Child 1.1
|_ Child 1.2
|_ Child 2
|_ Child 2.1
|_ Child 2.2
Run Code Online (Sandbox Code Playgroud)
嵌套集合模型的结构如下:
___________________________________________________________________
| Root |
| ____________________________ ____________________________ |
| | Child 1 | | Child 2 | |
| | __________ _________ | | __________ _________ | |
| | | C 1.1 | | C 1.2 | | | | C 2.1 | | C 2.2 | | |
1 2 3_________4 5________6 7 8 9_________10 11_______12 13 14
| |___________________________| |___________________________| |
|___________________________________________________________________|
Run Code Online (Sandbox Code Playgroud)
插入节点很简单:
$child1 = $root->children()->create(['name' => 'Child 1']);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6407 次 |
| 最近记录: |