Laravel сохраняет/обновляет многие для многих отношений
Может ли кто-нибудь помочь мне в том, как сохранить многие отношения? У меня есть задачи, у пользователя может быть много задач, и задача может иметь много пользователей (многие из многих), чего я хочу достичь, так это то, что в форме обновления администратор может назначить нескольким пользователям конкретную задачу. Это делается через html множественный выбор ввода
name="taskParticipants[]"
Ловушка здесь заключается в том, что через ту же форму (ввод) вы можете добавлять/удалять пользователей, поэтому я должен использовать sync().
Может быть, я должен начать с самого начала, но не знаю, с чего начать...
Это моя модель пользователя:
public function tasks()
{
return $this->belongsToMany('Task','user_tasks');
}
Модель задачи
public function taskParticipants()
{
return $this->belongsToMany('User','user_tasks');
}
TaskController
public function update($task_id)
{
if (Input::has('taskParticipants'))
{
foreach(Input::get('taskParticipants') as $worker)
{
$task2 = $task->taskParticipants->toArray();
$task2 = array_add($task2,$task_id,$worker);
$task->taskParticipants()->sync(array($task2));
}
}
}
Это структура таблиц задания Идентификатор | название | срок
user_tasks
id|task_id|user_id
Ответы
Ответ 1
TL;DR; Используйте sync
со вторым параметром false
Отношение "многие ко многим" belongsToMany
для обеих моделей:
// Task model
public function users()
{
return $this->belongsToMany('User', 'user_tasks'); // assuming user_id and task_id as fk
}
// User model
public function tasks()
{
return $this->belongsToMany('Task', 'user_tasks');
}
Чтобы добавить новое отношение, используйте attach
или sync
.
Разница между двумя:
1 attach
добавит новую строку в сводную таблицу без проверки ее наличия. Хорошо, когда у вас есть дополнительные данные, связанные с этим отношением, например:
User
и Exam
, связанных со сводной таблицей attempts: id, user_id, exam_id, score
Я полагаю, что это не то, что вам нужно в вашей ситуации:
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
$user->tasks()->attach([5,6,7]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,5,6,7]
2 sync
, либо удалит все отношения и настроит их заново:
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
$user->tasks()->sync([1,2,3]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3]
или он установит новые отношения, не отсоединяя предыдущий И без добавления дубликатов:
$user->tasks()->sync([5,6,7,8], false); // 2nd param = detach
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,7,8]
Ответ 2
Здесь мои заметки о том, как сохранить и обновить все отношения "Красноречивый".
в Один к одному:
Вы должны использовать HasOne для первой модели и BelongsTo для второй модели
чтобы добавить запись в первую модель (HasOne), используйте функцию сохранить
пример: $post->comments()->save($comment);
чтобы добавить запись во вторую модель (BelongsTo), используйте функцию связать
пример: $user->account()->associate($account); $user->save();
в От одного до большого:
Вы должны использовать HasMany для первой модели и BelongsTo для второй модели
чтобы добавить запись в первую таблицу (HasMany), используйте функции сохранить или saveMany
пример: $post->comments()->saveMany($comments);
чтобы добавить запись во вторую модель (BelongsTo), используйте функцию связать
пример: $user->account()->associate($account); $user->save();
в От многих до многих:
Вы должны использовать BelongsToMany для первой модели и BelongsToMany для второй модели
чтобы добавить записи в сводной таблице, используйте функции прикрепить или синхронизировать
-
обе функции принимают одиночный идентификатор или массив идентификаторов
-
разница заключается в проверке присоединения, если запись уже существует в сводной таблице, а sync dont
Пример: $user->roles()->attach($roleId);
в Полиморфное от одного до большого:
Вы должны использовать MorphMany для основной модели и MorphTo для всех моделей (***)
чтобы добавить записи во все другие модели, используйте сохранить
пример: $course->tags()->save($tag);
сводная таблица должна иметь следующие столбцы:
. идентификатор основной модели
. (*** возможно) ID
. (*** способный) Тип
в Полиморфное много для многих:
Вы должны использовать MorphByMany в основной модели и MorphToMany на всех моделях (***)
чтобы добавить записи во все другие модели, используйте сохранить или saveMany
пример: $course->tags()->save($tag);
пример: $course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);
сводная таблица должна иметь следующие столбцы:
. идентификатор основной модели
. (*** возможно) ID
. (*** способный) Тип
в имеет много сквозных (ярлык):
Вы должны использовать HasManyThrough в первой таблице и иметь нормальные отношения на двух других таблицах
это не работает для отношений ManyToMany (где theres сводная таблица)
однако это простое и простое решение для этого.
Вот статья, которую я написал, вдохновленная этим ответом. Важно проверить: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
Ответ 3
Функция sync
стирает возникающие отношения и делает ваш массив полным списком отношений. Вы хотите attach
вместо этого добавлять отношения, не удаляя других.