架构
我有以下数据库架构:
=== 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/