Laravel создает или обновляет без двух запросов

Я пытаюсь использовать одну форму для создания и обновления. Оба действия сохраняются с помощью этого метода:

public function store() { $data = Input::all(); $data['company_id'] = Auth::user()->company_id; $validator = Validator::make($data, Feature::$rules); if($validator->fails()) { return Redirect::back()->withErrors($validator)->withInput(); } Feature::firstOrNew(['id' => Input::get('id')])->update($data); return Redirect::route('features.index'); } 

Как я могу переписать эту строку:

 Feature::firstOrNew(['id' => Input::get('id')])->update($data); 

Так что сначала не извлекать объект из базы данных? В этом нет необходимости; Я ничего не делаю с этим. Он должен либо выдать INSERT если установлен Input::get('id') , либо UPDATE если это не так.

Если у вас есть все поля, которые не охраняются в вашей модели, я думаю, вы можете сделать это следующим образом:

 $feature = new Feature($data); $feature->exists = Input::has('id'); $feature->save(); 

Если у вас есть защищенные поля, вы можете сначала отпереть его:

 $feature = new Feature(); $feature->unguard(); $feature->fill($data); $feature->exists = Input::has('id'); $feature->reguard(); $feature->save(); 

reguard() самом деле не нужен, если вы не делаете ничего с моделью.

Это то, что я использую:

 Model::updateOrCreate( ['primary_key' => 8], ['field' => 'value', 'another_field' => 'another value'] ); 

Второй параметр – это массив данных для модели, которую вы хотите сохранить.

Раньше у меня была эта проблема и я создал приемлемый запрос на перенос на Laravel, который вы можете использовать. Попробуйте код ниже. Метод, в котором вы в основном нуждаетесь, – findOrNew .

 public function store($id=0) { $user = User::findOrNew($id); $data = Input::all(); if (!$user->validate($data)) { return Redirect::back()->withInput()->withErrors($user->errors); } $user->fill($data); $user->save(); return Redirect::to('/')->with('message','Record successfully saved!'); } 

Моя модель использует самооценку, но вы можете создать свою собственную проверку, как у вас сейчас.

Найти или Создать на основе идентификатора первичного ключа

 $data = Input::all(); $user = User::findOrNew($id); // if exist then update else insert $user->name= $data['user_name']; $user->save(); 

Первый или Новый на основе непервичного ключевого файла

 $user = User::firstOrNew(['field' => $data['value'] ]); $user->name= $data['user_name']; $user->save(); 

Первый или Новый на основе непервичного ключа

 $user = User::firstOrNew([ 'field1'=>$data['value1'], 'field2'=>$data['value2'] ]); $user->name= $data['user_name']; $user->save(); 

Если вы используете методологию маршрутизатора ресурсов laravel, вы должны использовать отдельный метод с именем update для обновления вашей модели, поэтому разделение может быть выполнено с помощью фреймворка. При этом все еще можно повторно использовать форму.

Если вы действительно хотите избежать нового метода обновления модели, вы можете переписать ее следующим образом:

 public function store() { $model = Input::has('id') ? ModelClass::findOrFail(Input::get('id')) : new ModelClass; $inputData = Input::all(); $validator = Validator::make($inputData, ModelClass::$rules); if ($validator->fails()) { return Redirect::back() ->withErrors($validator) ->withInput(); } $model->fill($inputData); $model->save(); return Redirect::route('modelclass.index'); } 

Вы можете попробовать следующее:

 $data = Input::except('_token'); $newOrUpdate = Input::has('id') ? true : false; $isSaved = with(new Feature)->newInstance($data, $newOrUpdate)->save(); 

Если $data содержит id/primary key он будет обновлен, иначе вставка будет выполнена. Другими словами, для обновления вам необходимо передать id/primary key в $data/attributes с другими атрибутами, а второй аргумент в методе newInstance должен быть true .

Если вы передадите метод false/default для newInstance он будет выполнять вставку, но $data не может содержать id/primary ключ. У вас есть идея, и эти три строки кода должны работать. $isSaved будет Boolean значением, true/false .

Вы можете написать код, используя одну строку:

 with(new Feature)->newInstance($data, array_key_exists('id', $data))->save(); 

Если $data содержит id/primary key то он будет обновлен, иначе будет выполнена вставка.