Подтвердить что ты не робот

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
4b9b3361

Ответ 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 вместо этого добавлять отношения, не удаляя других.