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

时间:2015-12-30 15:40:52

标签: 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

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!)*/ } } 与类别

的最新版本有关

我想要什么?

我希望将这种关系表现为Laravel的模特。 我设法开始了:

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
    }
}

-

revisions()

我希望找到一种高效的方法来为Module模型创建{{1}}方法。我怎么能这样做?

注意:如果您建议架构更改,我不介意,只要它比我目前更好!

1 个答案:

答案 0 :(得分:1)

从你的问题不清楚我们是否有一条直线下降(例如x=(('a', 'b'), ('foo', 'bar')) foo = [[y] for a in x for y in a] names = ["One", "Two", "Three", "Four"] df = pd.DataFrame({names[ix]: foo[ix] for ix in range(4)}) df = df[names] >>> print(df[names]) One Two Three Four 0 a b foo bar )或类似的东西:

revision #1 -> revision #2 -> revision #3 -> ...

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

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

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

然后你可以这样做:

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

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