在laravel重新加载模型

时间:2014-05-13 22:55:25

标签: php laravel unit-testing laravel-4 eloquent

在我的一些测试中,我有一个我创建的用户模型,并且我运行了一些需要保存某些属性的方法。在rails中,我通常会调用类似user.reload的东西来重新填充数据库中的属性。

laravel有办法做到这一点吗?我通读了api并找不到适合它的方法:http://laravel.com/api/4.1/Illuminate/Database/Eloquent/Model.html有关“正确”方法的任何想法吗?

5 个答案:

答案 0 :(得分:45)

有一个commit提交给8月份制作的4.0分支添加reload()方法,但到目前为止它还没有与新的Laravel分支合并。

但是...... Laravel 5正在提供一个" fresh()"将返回当前模型的新实例的方法。一旦您使用Laravel 5.0或更高版本,您就可以重新加载这样的模型:

$model = $model->fresh(); 

请注意,fresh()不会直接更新现有的$ model,只会返回一个新实例,这就是为什么我们需要使用" $ model =&# 34;。它还接受一个参数,它是一个你希望它急切加载的关系数组。

如果您还没有使用Laravel 5,但想要相同的功能,可以将此方法添加到您的模型中:

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

答案 1 :(得分:28)

感谢PR#19174可用,因为5.4.24refresh method

$model->refresh();

这样您就不必处理重新分配,如fresh方法的其他答案中所示,如果您想要刷新已传递到另一个方法的模型,这通常没有用,因为变量赋值将超出调用上下文稍后使用的范围。

答案 2 :(得分:9)

我也看不到它。看起来你必须:

$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是一个非常大的课程。

答案 3 :(得分:5)

  • 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'

答案 4 :(得分:1)

我相信@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()是要走的路