Обновление Laravel Eloquent только в случае внесения изменений

53

Есть ли способ обновить запись в Laravel, используя красноречивые модели, только если было внесено изменение в эту запись? Я не хочу, чтобы какой-либо пользователь запрашивал базу данных без уважительной причины снова и снова, просто нажав кнопку, чтобы сохранить изменения. У меня есть функция javascript, которая включает и отключает кнопку сохранения в соответствии с тем, изменилось ли что-то на странице, но я хотел бы знать, можно ли также выполнять эту функцию на стороне сервера. Я знаю, что могу сделать это сам (это означает: не обращаясь к внутренней функциональности фреймворка), просто проверяя, изменилась ли запись, но прежде чем делать это таким образом, я хотел бы знать, действительно ли модель красноречия Ларавела так что мне не нужно повторно изобретать колесо.

Так я использую для обновления записи:

$product = Product::find($data["id"]);
$product->title = $data["title"];
$product->description = $data["description"];
$product->price = $data["price"];
//etc (string values were previously sanitized for xss attacks)
$product->save();
  • 0
    Почему бы не включить ведение журнала базы данных, а затем проверить журналы, чтобы увидеть, какой запрос Eloquent фактически выполняет при сохранении: вы можете быть приятно удивлены
  • 1
    Обратите внимание, что модели Laravel содержат dirty флаг, который используется для определения того, действительно ли требуется обновление базы данных, и этот флаг устанавливается путем сравнения исходных значений столбца find со значениями в точке, где вы выполняете сохранение.
Показать ещё 1 комментарий
Теги:
eloquent

3 ответа

110
Лучший ответ

Вы уже это делаете!

save() проверяет, изменилось ли что-то в модели. Если он не выполнил db-запрос.

Здесь соответствующая часть кода в Illuminate\Database\Eloquent\Model@performUpdate:

protected function performUpdate(Builder $query, array $options = [])
{
    $dirty = $this->getDirty();

    if (count($dirty) > 0)
    {
        // runs update query
    }

    return true;
}

Метод getDirty() просто сравнивает текущие атрибуты с копией, сохраненной в original при создании модели. Это делается в методе syncOriginal():

public function __construct(array $attributes = array())
{
    $this->bootIfNotBooted();

    $this->syncOriginal();

    $this->fill($attributes);
}

public function syncOriginal()
{
    $this->original = $this->attributes;

    return $this;
}

Если вы хотите проверить, загрязнена ли модель, просто вызовите isDirty():

if($product->isDirty()){
    // changes have been made
}

Или, если вы хотите проверить определенный атрибут:

if($product->isDirty('price')){
    // price has changed
}
  • 0
    Замечательно. Спасибо. Теперь мне интересно, как я могу получить доступ к этому грязному флагу, чтобы узнать, была ли сделана попытка обновления без внесения каких-либо изменений? Я имею в виду: возвращение для этого действия?
  • 1
    @DaseinA Вы можете использовать isDirty() для этого. Смотрите обновленный ответ
Показать ещё 1 комментарий
9

Мне нравится добавлять этот метод, если вы используете форму редактирования, вы можете использовать этот код для сохранения изменений в вашей функции update(Request $request, $id):

$post = Post::find($id);    
$post->fill($request->input())->save();

помните, что вы должны называть свои входы одним и тем же именем столбца. Функция fill() выполнит всю работу за вас:)

  • 2
    На самом деле это ответ, который я искал, я забыл о fill имени и о том, как массово передать ему запрос. Спасибо! Мне не нужно было передавать идентификатор, так как я обновляю, так что его уже есть $request->id .
0

Вы можете использовать getChanges() в модели Eloquent даже после сохранения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню