Отношения многие ко многим, как добавлять существующие значения в таблицу, если они уникальны?

89
11 декабря 2021, 07:30

Вообщем у меня есть код, который добавляет Теги из ArticleController - в таблицу Tag значения(поле алиас уникальное), и сохраняется в промежуточную таблицу (т.к. есть связь многие ко многим ) Как сделать так, чтобы если есть уже такой тег с уникальным ключем alias - он пропускал его(или просто обновлял) и не было ошибки, что поле уникально и нельзя добавить в БД

    public function addArticle($request){
     $data = $request->except('_token');
     /* Блок для тегов*/
     if ($data['tags_title']){
         $data['tags_alias'] = $this->transliterate($data['tags_title']);
     }
     $tags = explode(',', $data['tags_title']);
     $tags_alias = array();
     foreach ($tags as $tag_alias){
         $tag_alias  = $this->transliterate($tag_alias);
         /*dump($tag_alias);*/
         array_push($tags_alias, $tag_alias);
     }
     $tags_merge = array_combine($tags, $tags_alias);
     /*dd($data, $tags, $tags_alias, $tags_merge);*/
    /*Блок для тегов закончен */

    if (empty($data['alias'])){ //если пустая ячейка в массиве data
        $data['alias'] = $this->transliterate($data['title']);
    }
    if ($this->one($data['alias'],false)){
        $request->merge(array('alias' => $data['alias']));
        $request->flash();
        return ['error' => 'Данный псевдоним уже используется'];
    }
    if($request->hasFile('img')) {
        $image = $request->file('img');
        if ($image->isValid()) {
            $str = str_random(8);
            $obj = new \stdClass();
            $obj->mini = $str.'_mini.jpg';
            $obj->max = $str.'_max.jpg';
            $obj->path = $str.'.jpg';
            $img = Image::make($image);
            $img->fit(Config::get('settings.articles_img_full')['width'],
                      Config::get('settings.articles_img_full')['height'])->
                      save(public_path().'/'.env('THEME').'/images/articles/'.$obj->path);
            $img->fit(Config::get('settings.articles_img')['max']['width'],
                Config::get('settings.articles_img')['max']['height'])->
            save(public_path().'/'.env('THEME').'/images/articles/'.$obj->max);
            $img->fit(Config::get('settings.articles_img')['mini']['width'],
                Config::get('settings.articles_img')['mini']['height'])->
            save(public_path().'/'.env('THEME').'/images/articles/'.$obj->mini);
            $data['img'] = json_encode($obj);
            $this->model->fill($data);
            if ($request->user()->articles()->save($this->model)) {
                    foreach ($tags_merge as $key => $value){
                            $this->model->tags()->create([
                                'title' => $key,
                                'alias' => $value
                            ]);

                    }
                    return ['session' => 'Материал добавлен'];
            }
        }
    }

}

вот такой код делает проверку и значение else - добавляет в базу, если поле Алиас новое

if ($request->user()->articles()->save($this->model)) {
                foreach ($tags_merge as $key => $value){
                    if (array_search($value, Tag::all()->pluck('alias')->toArray())){
                        continue;
                    }
                    else{
                        $this->model->tags()->create([
                            'title' => $key,
                            'alias' => $value
                        ]);
                    }

                }
                    return ['session' => 'Материал добавлен'];
            }

что мне нужно подставить на место continue - чтобы просто привязало запись из существующей БД ?

Answer 1

1) Найдем существующий или создадим новый тег при помощи метода firstOrCreate().

2) Приатачим тег к текущей модели при помощи метода attach() отношения belongsToMany

if ($request->user()->articles()->save($this->model)) {
    foreach ($tags_merge as $key => $value){
        $tag = Tag::firstOrCreate([
            'title' => $key,
            'alias' => $value
        ]);
        $this->model->tags()->attach($tag->id);
    }
    return ['session' => 'Материал добавлен'];
}

Для обновления (будет работать и в создании) можно использовать метод sync() отношения belongsToMany:

if ($request->user()->articles()->save($this->model)) {
    $tags = [];
    foreach ($tags_merge as $key => $value){
        $tag = Tag::firstOrCreate([
            'title' => $key,
            'alias' => $value
        ]);
        $tags[] = $tag->id;
    }
    $this->model->tags()->sync($tags);
    return ['session' => 'Материал добавлен'];
}

sync() сам сделает нужные attach() и detach() на основе массива, который в него передадите.

READ ALSO
Laravel переодическое удаление старых записей

Laravel переодическое удаление старых записей

В БД есть таблица нотификаций, из которой нужно раз в месяц удалять устаревшие записи

116
On dublicate key Ошибка Mysqli

On dublicate key Ошибка Mysqli

Не пойму, что не нравится то ему?

121
Иерархия пользователей

Иерархия пользователей

Подскажите, на wordpress у пользователей есть личный кабинет, через который они могут пригласить других пользователейКак можно потом эту связь...

174
php preg_match как запретить такие символы как \ / : * ? " ' < > |

php preg_match как запретить такие символы как \ / : * ? " ' < > |

Привет помогите с preg_match в php как написать выражение что бы не содержались символы такие как

73