Как перезагрузить/обновить модель из базы данных в 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()
- это путь