Какова наилучшая практика массовых обновлений отношений?
Например, у меня есть 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);
}
}
Может быть, хорошо для многих отношений, но выглядит как плохо.И у меня проблема с проверкой массива данных.
Я пытаюсь найти ответ на свой вопрос, но безрезультатно.