Синхронизация Laravel создает дублирующую дату в сводной таблице, если выбрано несколько изображений

Почему синхронизация дублирует синхронизацию в сводной таблице, если я выбираю больше, чем изображение?

В моем приложении при добавлении нового конкурса пользователь может выбрать одно или несколько изображений/документов, и путь к файлу будет сохранен в таблице файлов и синхронизирован с данными в сводной таблице competition_file.

Вот интерфейс создания

Вот функция магазина на моем контроллере

  public function store($competition, Request $request, Team $team)
    {

        if ($request->has('photos') && is_array($request->photos)) {

            $files = $this->filesRepo->getByUuids($request->photos);

            $fileId = $files->pluck('id')->toArray();

            if ($files->isNotEmpty()) {

                $forSync = array_fill_keys($fileId, ['competition_id' => $competition,'team_id' => $request->team,'type' => $request->type,'share_type' => $request->share_type]);

                $team->documents()->sync($forSync);

            }
        }

        return redirect(route('documents.index',$competition))->with('success', 'Document updated.');

    }

Вот коды отношений в моей модели

  public function documents()
{
    return $this->belongsToMany(File::class,'competition_file','team_id','file_id')->wherePivot('type', 'document');
}

Когда я выбираю более одного изображения, как показано ниже, оно создает дубликат в таблице competition_file.

Вот как это сохраняется в сводной таблице competition_file с повторяющимися данными

Но если сбросить данные до sync, когда я выбрал два изображения, он показывает только два массива, см. Коды ниже.

 public function store($competition, Request $request, Team $team)
    {

        if ($request->has('photos') && is_array($request->photos)) {

            $files = $this->filesRepo->getByUuids($request->photos);

            $fileId = $files->pluck('id')->toArray();

            if ($files->isNotEmpty()) {

                $forSync = array_fill_keys($fileId, ['competition_id' => $competition,'team_id' => $request->team,'type' => $request->type,'share_type' => $request->share_type]);

                dd($forSync);

                $team->documents()->sync($forSync);

            }
        }

        return redirect(route('documents.index',$competition))->with('success', 'Document updated.');

    }

Результат

И если я удалю Dump и перезагружу ту же страницу, она синхронизируется правильно

А если я повторю попытку без Dump, и если я выберу два изображения и сохраню их, создастся дубликат?

Мне нужно знать, что может создавать дублирующую синхронизацию.

Я надеюсь, что мой вопрос ясен, может кто-нибудь, пожалуйста, помогите мне.

Установите уникальное ограничение на уровне БД (например, ['competition_id', 'team_id', 'file_id'] as unique_competition_team_file), затем продолжите работу. Вам нужно будет изменить проверку запроса, проверив, существует ли уже тот же файл (возможно, с пользовательским классом правил), но вы защитите свою БД от ненужных данных, что (должно быть) конечной целью.

Tpojka 20.12.2020 19:38

Вам не нужно 'team_id' => $request->team в array_fill_keys, так как синхронизация происходит через отношение documents к командному объекту — team_id должен заполняться автоматически

Donkarnash 20.12.2020 19:55

@Donkarnash, почему идентификатор команды заполняется автоматически? при этом пользователю нужно выбрать команду при добавлении файлов

Jareer 21.12.2020 05:10

@Donkarnash пользователь может выбрать команду 1 или команду 2 при добавлении файла, поэтому я использовал 'team_id' => $request->team

Jareer 21.12.2020 05:16

@Donkarnash, но если я удалю $forSync = array_fill_keys($fileId, ['competition_id' => $competition,'type' => $request->type,'share_type' => $request->share_type]); и отправлю team_id, будет синхронизировано значение null, в чем может быть проблема?

Jareer 21.12.2020 05:20

Но тогда что такое параметр $team во внедрении метода? Когда вы синхронизируете связанную запись, идентификатор экземпляра модели, который вызывает отношение, заполняется автоматически, что является преимуществом, кроме того, что он удаляет записи для идентификаторов, которые отсутствуют в синхронизации.

Donkarnash 21.12.2020 05:20
team_id will be synced null ? Нет, он автоматически заполнит team_id $team->id. Если вам нужно, чтобы team_id соответствовал указанному в $request, вы можете сделать Team::findOrFail($request->team)->documents()->sync([...])
Donkarnash 21.12.2020 05:21

@Donkarnash, когда я dd($team->id); показывает ноль?

Jareer 21.12.2020 05:24

Тогда вам стоит попробовать $forSync = array_fill_keys($fileId, ['competition_id' => $competition,'type' => $request->type,'share_type' => $request->share_type]); и Team::findOrFail($request->team)->documents()->sync($forSync‌​);

Donkarnash 21.12.2020 05:30
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout.
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout.
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для...
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
1
9
325
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Только на пользу последующим посетителям.

public function store($competition, Request $request, Team $team)
{

    if ($request->has('photos') && is_array($request->photos)) {

        $files = $this->filesRepo->getByUuids($request->photos);

        $fileId = $files->pluck('id')->toArray();

        if ($files->isNotEmpty()) {

            $forSync = array_fill_keys($fileId, [
                'competition_id' => $competition,
                'type' => $request->type,
                'share_type' => $request->share_type
            ]);

                
            //If the implicit route model binding is not working
            //if $team is null or you need to explicitly set the team
            //selected by user and which is not passed as route param
            Team::findOrFail($request->team)->documents()->sync($forSync);

        }
    }

    return redirect(route('documents.index',$competition))
        ->with('success', 'Document updated.');

}

Другие вопросы по теме