请教 Laravel Eloquent 模型关联嵌套扁平化

第一次发帖,有不对之处请指正!我有这样的模型关系:

class Member extends Model{
    public function parent()
    {
        return $this->belongsTo(self::class, 'pid', 'id');
    }

    public function ancestors()
    {
        return $this->parent()->with('ancestors');
    }
}

我在控制器这样定义的:

use App\Models\Member;
class MembersController extends Controller
{
    public function membAncestor($id)
    {
        $member = Member::with('ancestors')->find($id);

        return $member;
    }
}

然后得到这样的结果:

[
   {
      "id": 107,
      "name": 'Parent',
      "pid": 104,
      'ancestors': [
         {
             "id": 104,
            "name":  'Parent1',
             "pid": 56,
             'ancestors': [
                {
                   "id": 56,
                   "name":  'Parent2',
                   "pid": 55,
                    'ancestors': [
                        {
                            "id": 55,
                            "name": 'Parent3',
                            "pid": 38,
                            'ancestors': [
                                {
                                   "id": 38,
                                  "name": 'Parent4',
                                   "pid": 35,
                                   'ancestors': null
                                }
                            ]
                        }
                    ]
                }
             ]
         }
      ]
   }
]

而我想要得到结果是这样的:

[
    {
        "id": 107,
        "name": 'Parent',
        "pid": 104,
    },
    {
        "id": 104,
        "name":  'Parent1',
        "pid": 56,
    },
    {
        "id": 56,
        "name":  'Parent2',
        "pid": 55,
    },
    {
        "id": 55,
        "name": 'Parent3',
        "pid": 38,
    },
    {
        "id": 38,
        "name": 'Parent4',
        "pid": 35,
    }
]
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5

用resource来格式化数据

4年前 评论

能说清楚点吗?API 资源我还不会用 :sweat_smile:。

4年前 评论

$members = MemberResource::collection(Member::all());
在MemberResource中
toArray方法重写
return [
'id'=>$this->id,
'name'=>$this->name,
'pid'=>$this-> parent->id,
]

4年前 评论

可能是我没讲清楚,我是通过 id 查询的,这样查到的结果只有一个层层嵌套的,所以是不能使用您所说的 API 资源集合,查文档之后改用 Resource,
use App\Models\Member;
use App\Http\Resources\Member as MemberResources;
class MembersController extends Controller
{
public function membAncestor($id)
{
return new MemberResources(Member::with('ancestors')->find($id));
}
}
但是只得到这样的结果:
{
"id": 107,
"name": 'Parent',
"pid": 104,
},
依然不是我想要的原本嵌套的关系拉平处于同一级。

4年前 评论
zhengwhizz

这种情况下建议增加一列 path 用于记录当前类别的父亲路径,如下:

[
    {
        "id": 107,
        "name": 'Parent',
        "pid": 104,
        "path": "-56-104-"
    },
    {
        "id": 104,
        "name":  'Parent1',
        "pid": 56,
        "path": "-56-"
    }
]

取的时候用 like 就行了。至于 path 的生成可以用模型事件直接在保存时存储进去。具体可以参考教程 3.1. 商品类目数据库结构设计

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!