Laravel Eloquent从自引用表和其他表的列中获取N级层次结构记录

2023-12-06

我在用Laravel 4 with MySQL后端。

我有两个数据库表,即 -surveyes and templates.

两张表都是self-referencing他们有column named parent那是foreign key该表本身。他们的记录在self referencing parent-child关系。

表格设计如下:

调查:

(PK)                        (FK_Surveyes)
Id  title       type        parent          sort_order  deleted_at
1   General     group       NULL            1           NULL
2   Where..?    question    1               1           NULL
3   abc..       answer      2               1           NULL
4   def..       answer      2               2           NULL
5   efg..       answer      2               3           NULL
6   ghi..       answer      2               4           NULL
7   What..?     question    1               2           NULL
8   hij..       answer      7               1           NULL
9   ijk..       answer      7               2           NULL
10  How..?      question    8               1           NULL
11  jkl..       answer      10              1           NULL
12  mnm..       answer      10              2           NULL
13  Special     group       NULL            2           NULL
14  Whom..?     question    13              1           NULL
15  opq..       answer      14              1           NULL
16  rst..       answer      14              2           NULL

模板:

(PK)(FK_surveyes)               (FK_Templates)
Id  survey_id       type        parent          sort_order  deleted_at
1   NULL            group       NULL            1           NULL
2   14              question    1               1           NULL
3   15              answer      2               1           NULL
4   16              answer      3               2           NULL
5   NULL            group       NULL            2           NULL
6   2               question    5               1           NULL
7   3               answer      6               1           NULL
8   4               answer      6               2           NULL
9   5               answer      6               3           NULL
10  6               answer      8               4           NULL
11  7               question    10              2           NULL
12  8               answer      10              1           NULL
13  9               answer      10              2           NULL

现在,我希望他们的记录也以同样的方式与N层次结构的级别。

这样我就创建了一个model for templates如下 :

class Template extends BaseModel{

    protected $table = 'templates';
    protected $softDelete = false;

    // loads only direct children - 1 level
    public function child()
    {
       return $this->hasMany('Template', 'parent');
    }

    // recursive, loads all descendants
    public function children()
    {
       return $this->child()->with('children')->orderBy('sort_order');
    }

    // parent
    public function parent()
    {
       return $this->belongsTo('Template','parent');
    }

    // all ascendants
    public function parentRecursive()
    {
       return $this->parent()->with('parentRecursive');
    }
}

我正在使用下面的方法(效果很好)来获取N模板的层次结构级别:

public function getTemplates(){
    $templates = Template::with('children')
                ->whereNull('parent')
                ->orderBy('sort_order', 'ASC');

    return $templates->toJson();
}

但现在,我想要这个专栏title来自surveyes桌子。专栏survey_id在表中templates is the foreign key表的surveyes.

我怎样才能实现它?

我已经更新了以下方法Template型号如下:

public function children()
{
   return $this->child()->with('children')->orderBy('sort_order')
        ->leftJoin('surveyes', 'surveyes.id', '=', 'templates.survey_id')->select('templates.*','surveyes.title');
}

But it 不提供分层记录,浏览器会挂起。我只有1500记录在templates table.

有人知道如何实现它吗?

EDIT :

我添加了一个方法来获取Survey模板中的模型如下:

public function survey()
    {
        return $this->belongsTo('D2D\Models\Survey','survey_id');
    }

并更新了children()方法如下:

public function children()
{
   return $this->child()
   ->with('survey','children')
   ->orderBy('sort_order');
}

现在我可以获得的记录Survey模型,但它返回的所有列Survey如下 :

{
    "id": 2,
    "survey_id": 522,
    "title": "Abc....?",
    "type": "question",
    "parent": 1200
    "survey": {
        "id": 522,
        "type": "question",
        "subtype": null,
        "title": "Abc....?",
        "parent": 1
    },
    "children": [{
        "id": 3,
        "survey_id": 526,
        "title": "aaa",
        "type": "answer",
        "parent": 2
        "survey": {
            "id": 526,
            "type": "answer",
            "subtype": null,
            "title": "aaa",
            "parent": 522
        },
        "children": []
    },
    {
        "id": 4,
        "survey_id": 527,
        "title": "bbb",
        "type": "answer",
        "parent": 2
        "survey": {
            "id": 527,
            "type": "answer",
            "title": "bbb",
            "parent": 522,
        },
        "children": []
    },
    ...
}

但我想要如下所示:

{
    "id": 2,
    "survey_id": 522,
    "title": "Abc....?", // Must be from Survey table
    "type": "question",
    "parent": 1200
    "children": [{
        "id": 3,
        "survey_id": 526,
        "title": "aaa", // Must be from Survey table
        "type": "answer",
        "parent": 2
        "children": []
    },
    {
        "id": 4,
        "survey_id": 527,
        "title": "bbb", // Must be from Survey table
        "type": "answer",
        "parent": 2
        "children": []
    },
    ...
}

有什么办法可以实现这一点吗?

我尝试更新 Survey() 方法,如下所示:

public function survey()
{
    return $this->belongsTo('D2D\Models\Survey','survey_id')->select(array('title'));
}

但在这种情况下,它会为每个元素给出 title=NULL 。

请让我知道如何实现这一目标?

Thanks.


此问题的一种可能的解决方案是使用嵌套集模型。这样就避免了递归查询的问题。有两个可用的 Laravel 包可以扩展 Eloquent 来实现嵌套集:Laravel-NestedSet and Baum。我了解您对现有数据有疑问;但是,制作一次性迁移脚本应该不会太难。您可以使用您选择的任何嵌套集库创建新模型;这些模型将具有设置调查的父节点的方法。您可以将新的调查数据放在一个新表中(您可以覆盖 Eloquent 中的表名称;看这里。然后,编写脚本或受保护的控制器操作以将现有调查迁移到新表。它将像这样工作(使用 laravel-nestedset 语法;Baum 类似):

$oldSurveys = Survey::all();
$oldSurveys->each(function($survey) {
    $newSurvey = NestedSurvey::create(array($survey->name, $survey->type ...etc));
});

$newSurveys = NestedSurvey::whereNotNull('parent_id');
$newSurveys->each(function($survey) {
    $parent = NestedSurvey::find($survey->parent_id);
    $survey->appendTo($parent)->save();
});

将所有调查导入新表后,您可以切换应用程序以使用新模型。

现在,您将能够在线性时间内获取任意深度的层次结构。由于您的模型扩展了 Eloquent,因此您可以像平常一样获取任何相关列。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Laravel Eloquent从自引用表和其他表的列中获取N级层次结构记录 的相关文章

  • 基于 PHP 的 CSV 编辑器? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有谁知道用 PHP 编写的在线 CSV 编辑器允许用户打开 编辑和保存给定的 CSV 文件 我能找到的只
  • 如何在Web服务中传递URL

    我想将此 URL 作为网址中的值传递http localhost h2orn php verify php email emails hash hash但是 我只能在 符号之前传递 我想传递所有 URL 我正在使用java网络服务 代码在这
  • Symfony php.ini Debian

    我在 Oracle VM VirtualBox 上使用 Debian 7 amd64 LAMP 服务器 我正在尝试安装 Symfony 但遇到了一些小问题 当我运行命令时 php my project name app check php
  • 这些加密算法有什么区别?

    两者有什么区别MCRYPT RIJNDAEL 128 MCRYPT RIJNDAEL 256 MCRYPT BLOWFISH等等 哪一种最适合网络数据传输 Rijandel 是 AES 的另一个名称 AES 是当前的 一个好的标准 算法 数
  • PSR-4 代码库中条令生成器的解决方法

    在 Windows 机器上使用 Symfony 2 和 Doctrine 我正在尝试 从现有模式生成实体 php app console doctrine mapping import force CoreBundle annotation
  • 适用于 Windows 的 PHP 支持的 GUI 应用程序

    我知道 PHP 是一种解释性语言 对于基于 Web 的事物来说 不是为在实际操作系统上运行 GUI 应用程序而设计的 但是有没有办法呢 基本上 是否有一个框架 系统允许我创建 本机 基本上是二进制文件 exe 看起来像带有本机控件和所有内容
  • 使用 php 将 HLS Segment (ts) 视频转换并加入到 mp4

    你好我正在使用这个工具 https github com Ejz HLSDownloader https github com Ejz HLSDownloader将 HLS 视频片段从 m3u8 播放列表下载到 ts 文件中 不 我不知道如
  • WooCommerce:用文本覆盖购物车价格

    我们有很多产品具有以下功能 No price 零价格 我们让它们可以通过内置挂钩购买 但购物车仍然将它们显示为具有0 price结账时 我们希望购物车和结帐摘要显示 特殊订单 或任何其他文本 但 WooCommerce 似乎使基于文本的价格
  • 从提交的表单中转义字符串中的字符

    每次发布帖子时 我都会得到转义字符 gt gt gt 我有一个多步骤表单 它将数据从一种表单传输到另一种表单 我将这些值与准备好的语句一起保存在数据库中 数据库中的值当前看起来像Paul s House 用户应该可以在字符串中使用单引号和双
  • 登录后所有页面都应该是https吗?

    这有点难以解释 但我会尽力 有一个网站 每个页面上都有登录表单 其中包含用户名 密码字段 这些页面未使用 SSL 用户填写用户名 密码并提交表单后 表单将被发送到 https 的身份验证页面 对于这种情况我有几个疑问 向 https 页面提
  • 使用 DOM 获取 div 的内容(包括子标签)

    我正在使用 DOM 来获取 div 标签的内容 但内部 html 部分未显示 功能是 dom new DOMDocument libxml use internal errors true dom gt loadHTMLFile url l
  • 将秒转换为天、小时、分钟和秒

    我想转换一个变量 uptime这是秒 分为天 小时 分钟和秒 Example uptime 1640467 结果应该是 18 days 23 hours 41 minutes 这可以通过以下方式实现DateTime http php net
  • 如何覆盖 phpunit 中导出的变量?

    我知道我可以设置环境变量 https phpunit de manual current en appendixes configuration html在我的 phpunit xml 里面
  • 解析 PHP 响应:未捕获的语法错误:意外的标记 <

    我正在使用 AJAX 来调用 PHP 脚本 我唯一需要从响应中解析的是脚本生成的随机 ID 问题是 PHP 脚本会引发许多错误 这些错误实际上很好 不会妨碍程序功能 唯一的问题是当我跑步时 parseJSON response I get
  • 需要使用 php 从远程服务器下载与 $_FILES 相同的内容[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 好的 我有处理图像上传的 php 代
  • 从多个选择列表中插入数据到mysql数据库(html形式)

    我制作了一个表格 其中有商店的 ID
  • php向多个收件人发送邮件

    我可以通过在邮件程序中定义 id 来将电子邮件发送到一个电子邮件 id 但是当用户在表单中键入 消息和电子邮件 id 时 我无法理解如何发送到多个收件人 例如 我正在显示一个带有两个文本区域的表单 一个用于电子邮件 ID 一个用于自定义消息
  • sqlsrv_num_rows 不返回任何值

    我正在尝试获取查询中返回的行数 while 循环遍历结果有效 但由于某种原因 sqlsrv num rows 不返回任何值 result SELECT from dtable WHERE id2 apple query sqlsrv que
  • PHP - 查找和比较日期

    你好 我有 foreach 我可以在其中获取数据库中的事件数据 我使用数据库中的日期名称 例如 event date 我需要在一个 div 中比较具有相同日期和输出的操作 例如我有这个事件 活动一 9 月 13 日 活动二 9 月 1 日
  • 处理查询字符串参数时 Codeigniter 缓存问题

    问候 我正在编写一个 CI Web 应用程序 它实现标准文件缓存功能 如下所示 this gt output gt cache n 我使用了段和查询字符串参数的组合 因此似乎遇到了问题 我在用例和输出类代码中看到的是 缓存仅基于段 像这样

随机推荐