Как перезагрузить/обновить модель из базы данных в Laravel?

В некоторых моих тестах у меня есть модель пользователя, которую я создал, и я запускаю некоторые методы, которые должны сохранять определенные атрибуты. В рельсах я обычно называл бы что-то вроде user.reload, которое бы повторно заполняло атрибуты из базы данных.

Есть ли способ в laravel сделать это? Я прочитал api и не смог найти способ для него: http://laravel.com/api/4.1/Illuminate/Database/Eloquent/Model.html Любые идеи о "правильном" способе сделать это?

Ответ 1

Я тоже не вижу этого. Похоже, вам придется:

$model = $model->find($model->id);

Вы также можете создать его самостоятельно:

public function reload()
{
    $instance = new static;

    $instance = $instance->newQuery()->find($this->{$this->primaryKey});

    $this->attributes = $instance->attributes;

    $this->original = $instance->original;
}

Просто протестировал его здесь, и он выглядит так, как будто он работает, но не уверен, насколько это далеко, но Eloquen - довольно большой класс.

Ответ 2

В августе была отправлена коммит, добавленный в ветку 4.0 для добавления метода reload(), но до сих пор он не был объединен с более новыми ветками Laravel.

Но... Laravel 5 предоставляет метод "fresh()", который будет возвращать новый экземпляр текущей модели. После того, как вы используете Laravel 5.0 или новее, вы можете перезагрузить модель следующим образом:

$model = $model->fresh(); 

Обратите внимание, что fresh() не обновляет напрямую вашу существующую модель $, она просто возвращает новый экземпляр, поэтому нам нужно использовать "$ model =". Он также принимает параметр с массивом отношений, которые вы хотите загружать.

Если вы еще не используете Laravel 5, но хотите использовать ту же функциональность, вы можете добавить этот метод в свои модели:

public function fresh(array $with = array())
{
    $key = $this->getKeyName();
    return $this->exists ? static::with($with)->where($key, $this->getKey())->first() : null;
}

Обновление: Если вы используете Laravel 5.4.24 или новее, теперь есть метод $model->refresh(), который вы можете использовать для обновления атрибутов объекта и связей на месте, а не для извлечения нового объекта, такого как fresh() делает. См. ответ джеффа Пакетта для более подробной информации по этому вопросу.

Ответ 3

Благодаря PR # 19174, доступному с 5.4.24, есть метод refresh.

$model->refresh();

Таким образом, вам не нужно иметь дело с переназначением, как показано в других ответах с помощью метода fresh, который, как правило, бесполезен, если вы хотите обновить модель, переданную в другой метод, потому что назначение переменной будет быть вне области для вызывающих контекстов, чтобы использовать позже.

Ответ 4

  • refresh() является изменяемой операцией: она перезагрузит текущий экземпляр модели из базы данных.
  • fresh() является неизменной операцией: она возвращает новый экземпляр модели из базы данных. Это не влияет на текущий экземпляр.
// Database state:
$user=User::create([
  'name' => 'John',
]);

// Model (memory) state:
$user->name = 'Sarah';

$user2 = $user->fresh();
// $user->name => 'Sarah';
// $user2->name => 'John'

$user->refresh();
// $user->name => 'John'

Ответ 5

Я считаю, что ответ @Antonio является наиболее правильным, но в зависимости от варианта использования вы также можете использовать комбинацию $model->setRawAttributes и $model->getAttributes.

$users = User::all();

foreach($users as $user)
{
    $rawAttributes = $user->getAttributes();

    // manipulate user as required 
    // ..
    // Once done, return attribute state

    $user->setRawAttributes($rawAttributes);
}

Основной недостаток этого заключается в том, что вы только "перезагружаете" атрибуты данных, а не какие-либо отношения, которые вы изменили, и т.д. Это также можно считать плюсом.

ИЗМЕНИТЬ

Как и L5 - fresh() - это путь