Eloquent sync() belongsToMany with pivot and nested children
Eloquent sync() belongsToMany with pivot and nested children
我想解决这个问题。我有一个 json 这样的:
[
{
"id": 2,
"title": "One",
"parent": {},
"children": [
{
"id": 3,
"title": "One One",
"parent": {
"id": 2,
"title": "One"
},
"children": [],
"value": 1
},
{
"id": 4,
"title": "One Two",
"parent": {
"id": 2,
"title": "One"
},
"children": [],
"value": 2
}
],
"value": 3
},
{
"id": 5,
"title": "Three",
"value": 3
}
]
如你所见,每个项目可以有一个child,也可以有一个child,也可以有一个child等等。它是嵌套的。
现在我想将这些 items
和每个 child 保存在与主元的 belongsToMany
关系中(在本例中:value
)。如果我想使用 sync()
,我必须在我的控制器中准备好我的所有项目:
<?php
/*Save $items*/
$items
= collect($request->input('data.items'))->mapWithKeys(function (
$item
) {
if (array_key_exists('value', $item)) {
$value = $item['value'];
} else {
$value = null;
}
return [
$item['id'] => compact('value'),
];
});
$user->items()->sync($items);
但这并不会递归遍历所有 children。我想到了类似的事情:
/*Save items*/
$items
= collect($request->input('data.items'))->mapWithKeys(function (
$item
) {
$traverse = function ($item) use (&$traverse) {
if (array_key_exists('value', $item)) {
$value = $item['value'];
} else {
$value = null;
}
foreach ($item['children'] as $child) {
$child = $traverse($child);
}
$children = ($item['children']);
return [
$item['id'] => compact('value', 'children'),
];
};
$item = $traverse($item);
但这行不通。
我想要的结果:
- 将每个
item
保存为 user
与枢轴 value
的 belongsToMany
关系
- 使用数据透视
value
递归保存所有 children
首先我想说的是你的数据其实是JSON,不是数组。所以在这里我写了一些代码,你可以看到我解码并从中得到一个数组(从 loop() 函数开始)。
据我了解,您想将所有项目值收集到 1 个数组中,该数组将用于保存 1 个用户的所有关系。因此,您可以使用该输出数组(请参阅 loop() 函数的底部)。
protected $result = [];
protected function deepDiveIntoNextLevel(array $array) {
foreach ($array as $item) {
$this->result[] = $item['value'];
if(!empty($item['children'])) {
$this->deepDiveIntoNextLevel($item['children']);
}
}
}
public function loop()
{
$json_array = '[
{
"id": 2,
"title": "One",
"parent": {},
"children": [
{
"id": 3,
"title": "One One",
"parent": {
"id": 2,
"title": "One"
},
"children": [],
"value": 1
},
{
"id": 4,
"title": "One Two",
"parent": {
"id": 2,
"title": "One"
},
"children": [],
"value": 2
}
],
"value": 3
},
{
"id": 5,
"title": "Three",
"value": 3
}
]';
$initial_array = json_decode($json_array, true);
$this->deepDiveIntoNextLevel($initial_array);
$result = $this->result;
// As output you may get an array, where you can have duplicates
sort($result);
// Or it can be not ordered
$relations_ids_odered = array_unique($result);
}
我想解决这个问题。我有一个 json 这样的:
[
{
"id": 2,
"title": "One",
"parent": {},
"children": [
{
"id": 3,
"title": "One One",
"parent": {
"id": 2,
"title": "One"
},
"children": [],
"value": 1
},
{
"id": 4,
"title": "One Two",
"parent": {
"id": 2,
"title": "One"
},
"children": [],
"value": 2
}
],
"value": 3
},
{
"id": 5,
"title": "Three",
"value": 3
}
]
如你所见,每个项目可以有一个child,也可以有一个child,也可以有一个child等等。它是嵌套的。
现在我想将这些 items
和每个 child 保存在与主元的 belongsToMany
关系中(在本例中:value
)。如果我想使用 sync()
,我必须在我的控制器中准备好我的所有项目:
<?php
/*Save $items*/
$items
= collect($request->input('data.items'))->mapWithKeys(function (
$item
) {
if (array_key_exists('value', $item)) {
$value = $item['value'];
} else {
$value = null;
}
return [
$item['id'] => compact('value'),
];
});
$user->items()->sync($items);
但这并不会递归遍历所有 children。我想到了类似的事情:
/*Save items*/
$items
= collect($request->input('data.items'))->mapWithKeys(function (
$item
) {
$traverse = function ($item) use (&$traverse) {
if (array_key_exists('value', $item)) {
$value = $item['value'];
} else {
$value = null;
}
foreach ($item['children'] as $child) {
$child = $traverse($child);
}
$children = ($item['children']);
return [
$item['id'] => compact('value', 'children'),
];
};
$item = $traverse($item);
但这行不通。
我想要的结果:
- 将每个
item
保存为user
与枢轴value
的 - 使用数据透视
value
递归保存所有
belongsToMany
关系
children
首先我想说的是你的数据其实是JSON,不是数组。所以在这里我写了一些代码,你可以看到我解码并从中得到一个数组(从 loop() 函数开始)。
据我了解,您想将所有项目值收集到 1 个数组中,该数组将用于保存 1 个用户的所有关系。因此,您可以使用该输出数组(请参阅 loop() 函数的底部)。
protected $result = [];
protected function deepDiveIntoNextLevel(array $array) {
foreach ($array as $item) {
$this->result[] = $item['value'];
if(!empty($item['children'])) {
$this->deepDiveIntoNextLevel($item['children']);
}
}
}
public function loop()
{
$json_array = '[
{
"id": 2,
"title": "One",
"parent": {},
"children": [
{
"id": 3,
"title": "One One",
"parent": {
"id": 2,
"title": "One"
},
"children": [],
"value": 1
},
{
"id": 4,
"title": "One Two",
"parent": {
"id": 2,
"title": "One"
},
"children": [],
"value": 2
}
],
"value": 3
},
{
"id": 5,
"title": "Three",
"value": 3
}
]';
$initial_array = json_decode($json_array, true);
$this->deepDiveIntoNextLevel($initial_array);
$result = $this->result;
// As output you may get an array, where you can have duplicates
sort($result);
// Or it can be not ordered
$relations_ids_odered = array_unique($result);
}