简体   繁体   English

如何从 Laravel 中的数据库重新加载/刷新 model?

[英]How to reload/refresh model from database in Laravel?

In some of my tests, I have a user model I have created and I run some methods that need to save certain attributes.在我的一些测试中,我创建了一个用户 model,我运行了一些需要保存某些属性的方法。 In rails, I would typically call something like user.reload which would repopulate the attributes from the database.在 Rails 中,我通常会调用user.reload之类的东西,它会重新填充数据库中的属性。

Is there a way in laravel to do that? laravel 有没有办法做到这一点? I read through the api and couldn't find a method for it: http://laravel.com/api/4.1/Illuminate/Database/Eloquent/Model.html Any ideas on the "right" way to do this?我通读了 api 但找不到方法: http://laravel.com/api/4.1/Illuminate/Database/Eloquent/Model.html关于“正确”方法的任何想法?

There was a commit submitted to the 4.0 branch made in August to add a reload() method, but so far it hasn't been merged with the newer Laravel branches. 8 月份向 4.0 分支提交了一个提交以添加 reload() 方法,但到目前为止它还没有与较新的 Laravel 分支合并。

But... Laravel 5 is providing a "fresh()" method that will return a new instance of the current model.但是... Laravel 5 提供了一个“fresh()”方法,它将返回当前模型的一个新实例。 Once you're using Laravel 5.0 or newer, you can reload a model like this:使用 Laravel 5.0 或更新版本后,您可以像这样重新加载模型:

$model = $model->fresh(); 

Note that fresh() doesn't directly update your existing $model, it just returns a new instance, so that's why we need to use "$model = ".请注意,fresh() 不会直接更新您现有的 $model,它只是返回一个新实例,因此我们需要使用“$model =”。 It also accepts a parameter which is an array of relations that you want it to eager load.它还接受一个参数,该参数是您希望它急切加载的一组关系。

If you aren't yet using Laravel 5 but you want the same functionality, you can add this method to your model(s):如果您还没有使用 Laravel 5 但您想要相同的功能,您可以将此方法添加到您的模型中:

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

Update: If you're using Laravel 5.4.24 or newer, there is now a $model->refresh() method that you can use to refresh the object's attributes and relationships in place rather than fetching a new object like fresh() does.更新:如果您使用 Laravel 5.4.24 或更新版本,现在有一个$model->refresh()方法,您可以使用它来刷新对象的属性和关系,而不是像fresh()那样获取新对象. See Jeff Puckett answer for more specifics on that.有关更多细节,请参阅 Jeff Puckett 的回答。

Thanks to PR#19174 available since 5.4.24 is the refresh method.感谢PR#19174可用,因为5.4.24refresh方法。

$model->refresh();

This way you don't have to deal with reassignment as is shown in other answers with the fresh method, which is generally not helpful if you want to refresh a model that's been passed into another method because the variable assignment will be out of scope for the calling contexts to use later.通过这种方式,您不必像其他答案中所示的使用fresh方法处理重新分配,如果您想刷新已传递给另一个方法的模型,这通常没有帮助,因为变量分配将超出范围稍后使用的调用上下文。

  • refresh() is a mutable operation: It will reload the current model instance from the database. refresh()是一个可变操作:它将从数据库重新加载当前模型实例。
  • fresh() is an immutable operation: It returns a new model instance from the database. fresh()是一个不可变的操作:它从数据库返回一个新的模型实例。 It doesn't affect the current instance.它不会影响当前实例。
// 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'

I can't see it either.我也看不出来Looks like you'll have to:看起来你必须:

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

You can also create one yourself:你也可以自己创建一个:

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

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

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

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

Just tested it here and it looks it works, not sure how far this goes, though, Eloquen is a pretty big class.刚刚在这里测试了它,它看起来有效,但不确定这能走多远,Eloquen 是一个相当大的类。

I believe @Antonio' answer is the most correct, but depending on the use case, you could also use a combination of $model->setRawAttributes and $model->getAttributes .我相信@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);
}

The primary downside to this is that you're only "reloading" the data attributes, not any relationships you've altered, etc. That might also be considered the plus side.这样做的主要缺点是您只是“重新加载”数据属性,而不是您更改的任何关系等。这也可能被认为是有利的一面。

EDIT编辑

As of L5 - fresh() is the way to go从 L5 开始 - fresh()是要走的路

In Laravel, you can refresh a model's data by using the refresh method.在 Laravel 中,您可以使用refresh方法刷新模型的数据。 This method retrieves the latest data for the model from the database and updates the model's attributes with that data.此方法从数据库中检索 model 的最新数据,并使用该数据更新模型的属性。 For example:例如:

$user = App\User::find(1);
$user->name = 'John Doe';
$user->save();

$user->refresh();

In this example, the refresh method is used to retrieve the latest data for the user with an ID of 1 from the database and update the $user model's attributes with that data.在此示例中, refresh方法用于从数据库中检索 ID 为 1 的用户的最新数据,并使用该数据更新$user模型的属性。 This is useful if another process has updated the data in the database and you want to ensure that the model's data is up to date.如果另一个进程更新了数据库中的数据并且您希望确保模型的数据是最新的,这将很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM