mysql - 如何在 Laravel 中表示有序递归关系?

标签 mysql laravel model laravel-5

架构

我有以下数据库架构:

=== modules ===
id: PK
name: String
current_revision: FK to revisions.id

=== revisions ===
id: PK
module_id: unsigned int, indexed, FK to modules.id
parent_revision: unsigned int, nullable, indexed, FK to revisions.id
content: string

示例数据

示例数据

模块:

(1, "Maths, 3)
(2, "Computing", 5)

修订:

(1, 1, null, "Maths - v1")
(2, 1, 1, "Maths- v2")
(3, 1, 2, "Maths - v3")
(4, 2, null, "Computing - v1")
(5, 2, 4, "Computing - v2")

解释

如您所见,parent_revision 与该模块的先前版本相关,如果它是该模块的第一个版本,则为 null

current_revision 与类别的最新版本相关

我想要什么?

我希望在 Laravel 中将这种关系表示为模型。 我设法开始了:

class Module extends Model
{
    public function currentRevision()
    {
        return $this->belongsTo(Revision::class, 'current_revision_id');
    }

    public function revisions()
    {
       /* Help! (I wish to return all the revisions for this module in
       order, starting from the current_revision. e.g. for the "Maths" 
       module it should return the revisions with IDs: [3, 2, 1] and               
       for the "Computing" module it should return: [4, 3]. Order 
       MATTERS!)*/
    }
}

-

class Revision extends Model
{
    public function module()
    {
        return $this->belongsTo(Module::class);
    }

    public function nextRevision()
    {
        return $this->hasOne(Revision::class, 'parent_revision');
    }

    public function previousRevision()
    {
        return $this->belongsTo(Revision::class, 'parent_revision');
    }

    public function previousRevisions()
    {
        // TODO: return ALL previous revisions
    }
}

我希望找到一种高效方法来为Module 模型创建revisions() 方法。我该怎么做?

注意:我不介意您建议架构更改,前提是它比我目前拥有的更好!

最佳答案

从您的问题中不清楚我们是否有直线下降(例如 revision #1 -> revision #2 -> revision #3 -> ...)或看起来像像这样:

Revision #1
 |  |
 |  +- Revision #2
 |      |
 |      +- Revision #4
 |
 +- Revision #3
 |
 ...

如果是简单的直线,那么@user3158900 的建议可能是最简单的。

如果它是修订的分支树,那么它会变得更加棘手。对于简单的父子关系,您可以在您的模型中这样设置它们:

public function parent()
{
    return $this->belongsTo(Revision::class, 'parent_revision');
}

public function children()
{
    return $this->hasMany(Revision::class, 'parent_revision');
}

然后你可以这样做:

$rev = Revision::find(42);

foreach ($rev->children as $child) {
    // do something with the children
}

$parent = $rev->parent;

// do something with the parent

请注意,children 关系将仅为直系后代 - 例如。修订版的直接子代,没有孙代、曾孙代等。要找到这些祖先,您需要递归遍历子代的关系。例如,

$rev = Revision::find(42);

foreach ($rev->children as $child) {
    // display the child content
    echo $child->content;

    // display the grandchildren's content
    foreach ($child->children as $grandchild) {
        echo $grandchild->content;
    }
}

要真正做到这一点是一种有效的方法,您可能需要编写一个递归函数。

关于mysql - 如何在 Laravel 中表示有序递归关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34532526/

相关文章:

mysql - 如何过滤掉具有匹配值的属性?

php - 测试数据库的最佳方法是什么(特定于 MYSQL)

导入时激活 MySQL 存储过程

Laravel 8 : Using Fortify in APIs

php - 在提交到数据库之前返回已获取的字段

php - 当多行不存在时也将它们连接起来

php - Laravel 5.5 Eloquent 在多于 1 列的情况下变得不同

javascript - 如何设置模型的加载顺序以避免关系错误?

ios - 更改 CoreData 模型 : retro compatibility

wpf mvvm 绑定(bind) View 到模型