【发布时间】:2019-06-29 02:11:43
【问题描述】:
大规模更新关系的最佳实践是什么?
例如,我有 Post 模型,它具有这样的关系:Lists(多对多)、Tags(多对多变形)、Author(一对一)。当我编辑Post时,我想附加几个Lists,几个Tags并设置author_id。
- 简单的方法:
$post->fill($request->all);
$post->saveOrFail();
$post->lists()->sync($request->lists);
$post->tags()->sync($request->tags);
不错,但如果关系超过两个,例如 10。恕我直言,不好。也许我错了。
- 艰难的路:
$post->fill($request->all);
$post->saveOrFail();
$post->massUpdateRelations($request->only(['lists', 'tags']));
function massUpdateRelations($data)
{
$this->massFill($data);
$this->massSave();
}
function massFill($data, $model = null)
{
$uses = array_flip(class_uses_recursive(static::class));
$relationModels = [];
if (is_null($model)) {
$model = $this;
}
if (!$model->wasRecentlyCreated) {
$relationModels[] = $model;
}
foreach ($data as $name => $value) {
if (is_array($value)) {
$relationInfo = $model->{$name}();
if ($relationInfo instanceof BelongsToMany) {
$relationInfo->sync($value);
} elseif ($relationInfo instanceof HasMany) {
$this->afterMassSave[] = function () use ($relationInfo, $value) {
$relationInfo->delete();
$relationInfo->createMany($value);
};
} elseif ($relationInfo instanceof HasOne) {
$this->afterMassSave[] = function () use ($relationInfo, $value) {
$relationInfo->delete();
$relationInfo->create($value);
};
} else {
$relation = $model->{$name};
$relationModels = array_merge($relationModels, $this->massFill($value, $relation));
}
} else {
if ($model->isFillable($name)) {
$model->setAttribute($name, $value);
}
}
}
$this->relationModels = $relationModels;
return $relationModels;
}
function massSave()
{
foreach ($this->relationModels as $relationModel) {
$relationModel->save();
}
foreach ($this->afterMassSave as $item) {
call_user_func($item);
}
}
也许对许多关系都有好处,但看起来很糟糕。并且在验证数据关系数组时遇到问题。
我正在尝试在我的问题中搜索答案,但没有效果。
【问题讨论】:
标签: php laravel relationship