Laravel sync() 与多维数组

Posted

技术标签:

【中文标题】Laravel sync() 与多维数组【英文标题】:Laravel sync() with multi-dimensional array 【发布时间】:2021-08-27 04:54:22 【问题描述】:

我的 Laravel 应用程序中的 2 个模型之间存在多对多关系。在这个数据透视表上,我存储了附加信息,包括需要转换为 json 的数组。

枢轴数据如下所示:

$pivotData = [
    'name' => 'Normal string',
    'items' => [
        '0' => 'String A',
        '1' => 'String B',
        '2' => 'String C',
    ]
]

在 ModelA 和 ModelB 之间的数据透视表上,我设置了 2 列(“名称”和“项目”)。 items 列设置为 json 列并按此进行强制转换。

创建 $modelA$modelB 后,我想将此数组与数据透视表中的 ModelB 同步,如下所示:

$modelA->relationshipMethod()->sync([
    $modelB->getKey() => $pivotData
])

当它运行时,我在/opt/project/vendor/laravel/framework/src/Illuminate/Support/Str.php 中收到一个错误Array to string conversion,这是因为“items”是一个数组。

如果您的数据透视表包含 json 列,我做错了什么?应该如何处理?

【问题讨论】:

但是它不会知道这个数据所属的$modelB的id。 $pivotData 是 $modelB 的模型表示还是已经创建?即使您的问题得到了很好的解释,它也会变得令人困惑,例如。为示例数据绘制数据库表以及 $pivotData 如何映射到它。 【参考方案1】:

sync 方法不会加载 pivot 模型上定义的$casts 变量,那么您需要将值存储为字符串:

$pivotData = [
    'name' => 'Normal string',
    'items' => json_encode([
        '0' => 'String A',
        '1' => 'String B',
        '2' => 'String C',
    ])
];

$modelA->relationshipMethod()->sync([
    $modelB->getKey() => $pivotData
]);

如果您想使用当前的 Pivot 模型,可以将 ModelA 模型更改为:

/**
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function relationshipMethod(): BelongsToMany

    return $this->belongsToMany(ModelB::class, PivotModel::class);

这仅适用于您的 PivotModel 扩展 Illuminate\Database\Eloquent\Relations\Pivot 而不是 Illuminate\Database\Eloquent\Model

https://laravel.com/docs/8.x/eloquent-relationships#defining-custom-intermediate-table-models

【讨论】:

【参考方案2】:

当你处理pivot表时,如果有额外的列,你必须在创建关系时在你的模型文件中声明

return $this->belongsToMany(ModelB::class)->withPivot('name', 'items');

只有模型键存在

在控制器中:

$pivotData = [
    'name' => 'Normal string',
    'items' => json_encode([
        '0' => 'String A',
        '1' => 'String B',
        '2' => 'String C',
    ])
];

$modelA->modelB()->syncWithPivotValues($modelB->getKey(), $pivotData);

您可以像文档中的示例一样在第一个参数中添加 modelB 的 ID 数组

$user->roles()->syncWithPivotValues([1, 2, 3], ['active' => true]);

或者你可以像这样使用同步:

$user->roles()->sync([1 => ['expires' => true], 2, 3]);

你可以在docs link看到更多

【讨论】:

以上是关于Laravel sync() 与多维数组的主要内容,如果未能解决你的问题,请参考以下文章

如何添加来自不同数组的多维数组值

循环多维数组 Laravel

如何在 Laravel 测试中发布多维数组?

Laravel - 无法使用刀片从多维数组中获取值

Laravel 多维数组不计算结果

在 laravel 中导出 excel 或 csv 中的多维数组