Существует две модели, master и child связанные по полю id в master и idmaster в childs, кроме того в child есть поле idvalue. которое является ссылкой на справочник. Например: существует запись в таблице master с id=30 существуют записи в таблице childs, например 3 шт: [id=1, idmaster=30, idvalue=10], [id=2, idmaster=30, idvalue=11], [id=3, idmaster=30, idvalue=12] поступил массив со значениями idvalue PHP: $truelist = array(10,13,14); задача: удалить те записи в child, для которых нет idvalue в пришедшем массиве, и добавить которых не хватает Как это сделать используя возможности eloquent? Используя hasMany, удалить - просто: PHP: $this->child()->whereNotIn('idvalue',$truelist)->delete(); А вот как добавить записи в childs, которых нет, но значения есть в массиве пройтись циклом по массиву $truelist и выбирать, типа: PHP: foreach($truelist as $idvalue) { $this->child()->where('idvalue',$idvalue)->firstOrCreate(['idvalue'=>$idvalue]); } можно, но это запрос к бд при каждой итерации выборки т.е. если такой массив 100 элементов - то печаль. подскажите, как это можно сделать более изящно, так же как и удаление?
Если прямо средствами Laravel, то upsert. Если религия позволяет написать чистый запрос, и это mysql, то можно insert ignore. --- Добавлено --- Это если в базе есть что-то вроде уникального ключа, составного.
@artoodetoo, у него не many-to-may --- Добавлено --- Хотя, если сделать связь на value, а не на показанный child, то будет many-to-many, и можно будет sync использовать. @snakenest Поля таблицы и сами таблицы лучше называть в соответствии с соглашениями ларки, он тогда кучу всего сам будет за тебя делать, без необходимости в пояснениях.
не совсем понял каким образом тут связь многие ко многим? таблица childs имеет три поля id - свой уникальный ключ idmaster - ссылка на таблицу мастер idvalue - ссылка на справочник values который используется в других таблицах Может вы имеете ввиду отношение - через (hasManyThrough)? можете объяснить это на примере или ссылку дать на какой-либо пример того что вы имели ввиду?
Спасибо! работает! переопределил связь PHP: public function values() { return $this->belongsToMany('App\Models\NSI','childs','idmaster','idvalue','id'); } И тогда заработал метод sync PHP: $this->values()->sync($truelist); правда пришлось повозиться с описанием параметров при установке связи, т.к. не очень понятно, что туда надо прописать. пришлось сделать такую вот штуку в AppServiceProvider PHP: use DB; use Illuminate\Http\Request; class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { if (env('SHOW_REQUEST',false)) { dump($this->app->request); } if (env('SHOW_QUERY',false)) { DB::listen( function ($query){ dump($query->sql); dump($query->bindings); }); } } чтобы увидеть реальные запросы к бд, и понять какие параметры, за что отвечают в belongsToMany
Ну вот чтоб не возиться с описанием параметров при установке связи, и надо соблюдать соглашения о наименованиях ларавеля везде, где возможно --- Добавлено --- Тогда можно проще писать: PHP: public function users(): \Illuminate\Database\Eloquent\Relations\BelongsToMany { return $this->belongsToMany(User::class); }
при создании БД с нуля - Да но при прикручивании уже существующей, да еще и которая работает праллельно с другими приложениями и сервисами..... не получится