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, если это не так.

Ответ 1

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

$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() на самом деле не нужен, если вы не делаете ничего с моделью.

Ответ 2

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

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

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

Ответ 3

Я использовал эту проблему и создал принятый запрос на растяжение на 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!');
}

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

Ответ 4

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

$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();

Ответ 5

Если вы используете методологию маршрутизатора ресурсов 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');
}

Ответ 6

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

$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, то он будет обновлен, иначе вставка будет выполнена.