雄辩的sync()属于带有透视图和嵌套子级的

时间:2019-10-05 22:02:33

标签: laravel eloquent laravel-collection

我想解决这个问题。我有一个像这样的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
  }
]

如您所见,每个项目可以有一个孩子,也可以有一个孩子,也可以有一个孩子,依此类推。它是嵌套的。

现在,我想将这些items和每个孩子保存为具有枢轴的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);

但是,这并不递归地适用于所有孩子。我想到了这样的东西:

/*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将每个belongsToMany保存为user的{​​{1}}关系
  • 使用枢轴value递归保存所有children

1 个答案:

答案 0 :(得分:1)

首先,我想提到的是您的数据实际上是JSON,而不是数组。因此,在这里我编写了一些代码,您可以在其中看到我解码并从中得到一个数组(从loop()函数开始)。

据我了解,您希望将所有项目值收集到1个数组中,该数组将用于保存1个用户的所有关系。因此,有了这个输出数组(请参见loop()函数的底部)。

Dictionary.dic