建议在PHP和Laravel上存储嵌套数据的最佳方法?[已关闭]

p8ekf7hl  于 11个月前  发布在  PHP
关注(0)|答案(2)|浏览(85)

已关闭。此问题需要details or clarity。它目前不接受回答。
**希望改进此问题?**通过editing this post添加详细信息并阐明问题。

14小时前关闭
Improve this question
我们需要存储用户提供的翻译,当前的设计在我认为足够的结构中解决了这个问题:
第一个月
因此,如果我有ID为1的项目A,其翻译为语言ID 2,则它将显示为:
1 | 2 | 1 | Hello World in Spanish
现在假设另一个用户继承了项目A的属性(称之为项目B),例如B也有属性parent_id,指向1(即A)
这样,在Laravel中,以下工作:

public function translations(){
        $language_ids = $this->item_languages()->pluck('language_id')->toArray();
        $item_ids = [$this->id];
        if ($this->hasParentItem()){
            array_push($item_ids, $this->parent_id);

            $parent_item = $this->parentItem()->first();
            $direct_parent_item = $parent_item;
            while ($parent_item->hasParentItem()) {
                array_push($item_ids, $parent_item->parent_id);
                $parent_item = $parent_item->parentItem()->first();
            }
        }
        return Translation::whereIn('language_id', $language_ids)->whereIn('item_id', $item_ids);
    }

字符串
一切看起来都很好!直到我们在问答中意识到孙子孙女不在前端工作,这也难怪!C项诞生了!它假定(并且确实)继承了祖父的A转换,因此上面的代码返回ID为1的转换。然而,C项自己的模型只直接引用了parent_id 2,而不是3!
因此,前端Map和显示翻译,没有办法知道翻译实际上属于当前正在使用的项目C!
我正在寻找两种可能的解决方案:
1.一个适当的解决方案,这可能会强制迁移系统中已经使用的现有数据:(我希望避免这种情况,尽管根据解决方案可能不会太糟糕。
1.或者,我想的是在翻译模型中添加accessor和mutator到一个附加的属性,并为检索到的集合中的每个翻译设置额外的属性direct_parent,以当前上下文中的直接父级(在示例代码中使用$direct_parent_item)。缺点是,如果将来没有上面的上下文,它会有些复杂和混乱,但可以在前端快速Map。
这样行吗?你有更好的替代方案如何修改原来的设计,如上述以适当的方式?
复制项目A的翻译不是一个选项,因为我们需要允许A也控制和更新继承的翻译。

q5lcpyga

q5lcpyga1#

在我看来,存储这些数据的更好方法是使用JSON对象。您可以将数据存储为

{
"id": 1,
"language_id": 2,
"item_id": 1,
"translation": "Hello World in Spanish",
"parents":[2,3]
}

字符串
如果这是一个关系数据库中的表,你可以使用JSON对象只为父母的一部分,如:

{
"parents": [2,3]
}

qpgpyjmq

qpgpyjmq2#

如果需要存储多层次深父关系,则需要一个新表,将每个父关系链接到其所有子关系,类似于:

parent_id | item_id | through | depth
1           2         null      1
1           3         2         2
2           3         null      1

字符串
每次创建一个新的模型时,你可以在递归函数中循环parent_id,并将它们插入这个表中,同时跟踪throughdepth。在这个模型中,你会有3个关系:

/** direct parent via parent_id on the model */
public function parent();

/** 
 * list of parents via the pivot table,
 * can order via depth so that the list mimics calling
 * the parent relation for each model in the chain
 */
public function parents();

/** 
 * relation via the pivot table containing all children,
 * can filter by depth  ->children()->where('depth', 1)
 */
public function children();


parents->first()将与->parentparents()->whereHasTranslation($key)->first()相同,其中whereHasTranslation是您可以实现的一些自定义作用域,将通过具有转换键的depth为您提供最接近或最远的顺序方向

相关问题