【问题标题】:Eloquent sync() belongsToMany with pivot and nested childrenEloquent sync() belongsToMany 与枢轴和嵌套的孩子
【发布时间】:2020-02-03 18:03:40
【问题描述】:

我想解决这个问题。我有一个这样的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 与枢轴value
  • 使用枢轴value递归保存所有children

【问题讨论】:

  • 你希望你有什么结果?请写下来,以便那些愿意提供帮助的人更容易阅读;)
  • 对不起,我补充了缺失的信息,

标签: laravel eloquent laravel-collection


【解决方案1】:

首先我想提一下,您的数据实际上是 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);
}

【讨论】:

    猜你喜欢
    • 2014-10-23
    • 1970-01-01
    • 2019-05-31
    • 2016-08-13
    • 2018-08-28
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    相关资源
    最近更新 更多