このブログの一番最初に書いた記事において、isDirty()に関して書きました。もう4年くらい前のことです。最近必要になって使用したところ、新たな発見がありました。
まず、tinkerを使用して、isDirty()の復習です。
factory()を使って、1つレコードを作成します。
>>> factory(App\User::class)->create();
=> App\User {#2987
name: "小林 春香",
email: "kana.yamamoto@example.org",
email_verified_at: "2019-07-02 03:01:25",
updated_at: "2019-07-02 03:01:25",
created_at: "2019-07-02 03:01:25",
id: 1,
}
作成したレコードの名前を更新しますが、DBでなくオブジェクトのみの更新のために、fill()を使用します。
>>> $user = User::find(1);
=> App\User {#2950
id: 1,
name: "小林 春香",
email: "kana.yamamoto@example.org",
email_verified_at: "2019-07-02 03:01:25",
created_at: "2019-07-02 03:01:25",
updated_at: "2019-07-02 03:01:25",
}
>>> $user->fill(['name' => '山田花子']);
=> App\User {#2950
id: 1,
name: "山田花子",
email: "kana.yamamoto@example.org",
email_verified_at: "2019-07-02 03:01:25",
created_at: "2019-07-02 03:01:25",
updated_at: "2019-07-02 03:01:25",
}
nameが変わりましたね。
実際、オブジェクトが更新したかどうかは、isDirty()を使います。
>>> $user->isDirty(); => true
変更していますね。
項目ごとはどうでしょう?
>>> $user->isDirty('name');
=> true
>>> $user->isDirty('email');
=> false
nameの変更がありますが、emailの変更はなしです。正しいです。
ここで、変更したオブジェクトをもとに対応するレコードをDBに保存します。
>>> $user->save(); => true
さて、この時点でのisDirty()の返り値は?
>>> $user->isDirty();
=> false
>>> $user->isDirty('name');
=> false
もう、isDirty()では、変更があったかどうかの判断はできません、何もDirtyではありません。
この時点、つまりオブジェクトの更新をDBに反映した時点でレコードが更新したかどうかを判断するには、isDirty()ではなく、wasChanged()を使用します。
>>> $user->wasChanged();
=> true
>>> $user->wasChanged('name');
=> true
>>> $user->wasChanged('email');
=> false
save()前のisDirty()の結果とまったく同じです。
実際には、こんなコードでwasChanged()は使われます。
...
$user->fill(['name' => '山田花子']);
if ($user->isDirty()) {
$user->save();
if ($user->wasChagned('name')) {
//nameが更新されたときのみ、以下のコードを実行
...
}
}
...
メルマガ購読の申し込みはこちらから。
