web-dev-qa-db-ja.com

Laravelのデータベースからモデルをリロード/リフレッシュする方法は?

一部のテストでは、作成したユーザーモデルを使用し、特定の属性を保存する必要のあるメソッドを実行しています。 Railsでは、通常、user.reloadこれは、データベースから属性を再移植します。

laravelでそれを行う方法はありますか?APIを読みましたが、そのためのメソッドが見つかりませんでした: http://laravel.com/api/4.1/ Illuminate/Database/Eloquent/Model.html これを行う「正しい」方法に関するアイデアはありますか?

30
matthew

私もそれを見ることができません。あなたがする必要があるように見えます:

$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はかなり大きなクラスです。

Reload()メソッドを追加するために8月に作成された4.0ブランチに commit が送信されましたが、これまでは新しいLaravelブランチとマージされていません。

しかし... Laravel 5は現在のモデルの新しいインスタンスをreturnする "fresh()"メソッドを提供しています。 Laravel 5.0以降を使用して、次のようにモデルをリロードできます。

_$model = $model->fresh(); 
_

fresh()は既存の$ modelを直接更新せず、新しいインスタンスを返すだけなので、 "$ 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()のように新しいオブジェクトを取得するのではなく、オブジェクトの属性と関係を更新するために使用できます。詳細については、Jeff Puckettの回答を参照してください。

48
orrd

5.4.24refreshメソッド であるため、 PR#19174 のおかげです。

$model->refresh();

この方法では、freshメソッドを使用した他の回答に示されているように、再割り当てを処理する必要がありません。これは、変数の割り当てにより、後で使用する呼び出しコンテキストのスコープ外になります。

37
Jeff Puckett
  • 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'
9
igaster

@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);
}
_

これの主な欠点は、変更した関係などではなく、データ属性のみを「リロード」することです。これもプラス面と見なされる場合があります。

[〜#〜] edit [〜#〜]

L5現在-fresh()が道です

1
Chris