[Laravel] Eloquentのあまり使われていない便利な機能 10個

あまり使われていなさそうな１０個の機能を紹介します。

## 確認環境
Laravel 6.x

## 1. 元データの取得
eloquentオブジェクトのデータを変更した後に、`getOriginal()`で元のデータを取得できます。

```python
use App\User;
$user = App\User::first();

$user->email;                   // nakamura.hanako@example.com

$user->name = "yamada.taro@example.com";
$user->getOriginal('email');    // nakamura.hanako@example.com

$user->name;                    // yamada.taro@example.com
```

## 2. モデルが変更されたかチェック
`isDirty()`でモデルに変更があったか確認できます。

```python
use App\User;
$user = App\User::first();
$user->isDirty();        // false

$user->email = "yamada.taro@example.com";
$user->isDirty();        // true
```
特定の属性が変更されたかも確認できます。

```python
$user->isDirty('email');  // true
$user->isDirty('status'); // false
```

## 3. 変更のプロパティを取得

`getChanges`でDB更新後に変更分を取得できます。

```python
$user->save();

$user->getChanges();
=> [
     "email" => "yamada.taro@example.net",
     "updated_at" => "2021-05-19 09:58:25",
   ]
```

`wasChanged`でDB更新後に変更のあったプロパティを確認できます。(boolean)

```python
$user->save();

$user->wasChanged('email');      // true

$user->wasChanged('status');     // false

$user->wasChanged();             // true

```

## 4. カスタム `deleted_at`
デフォルトで、ソフトディレートは `deleted_at`カラムが使用されます。これは、`DELETED_AT`プロパティで変更ができます。

```python3
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
    use SoftDeletes;

     * The name of the "deleted at" column.
     *
     * @var string
     */
    const DELETED_AT = 'is_deleted';
}
```
またはアクセサでも変更できます。

```python
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
    use SoftDeletes;

    public function getDeletedAtColumn()
    {
        return 'is_deleted';
    }
}
```

## 5. 関連のあるモデルも同時に更新
`push()`メソッドで変更のあるモデルと、その関連するモデルを同時に更新できます。

```python
class User extends Model
{
    public function user_profile()
    {
        return $this->hasOne('App\UserProfile');
    }
}

use App\User;
$user = User::first();
$user->email = 'test30@exmaple.co.jp';
$user->user_profile->nickname = 'bob';

$user->push(); // ここで userとuser_profileのレコードがDBに反映されます。
```

## 6. 更新データを取得

`fresh()`を使うとDBから更新データを取得できます。

```python
use App\User;
$user = User::first();
$user->email;                    // test30@exmaple.co.jp

## ここでDBのレコードを更新 e.g) emailを"test10@example.co.jp"に変更

$updatedUser = $user->fresh();
$updatedUser->email;             // test10@exmaple.co.jp

$user->email;                    // test30@exmaple.co.jp
```
## 7. 更新データを既存のモデルに反映
`refresh()`を使うとDBから更新データを取得し、既存のモデルに反映します。

```python
use App\User;
$user = User::first();
$user->email;                    // test10@exmaple.co.jp

## ここでDBのレコードを更新 e.g) emailを"test50@example.co.jp"に変更

$user->refresh();
$user->email;                    // test50@exmaple.co.jp

```

## 8. 同一モデルか確認
`is()`を使うと同一モデルか確認できます。

下記全てが同一なら、同一モデルとして判断されます。
・ID
・参照しているテーブル
・DB接続設定


```python
use App\User;
$user = User::find(1);
$sameUser = User::find(1);
$diffUser = User::find(2);

$user->is($sameUser);       // true
$user->is($diffUser);       // false
```

## 9. モデルのコピー
`replicate()` を使ってモデルをコピーできます。 

```python
use App\User;
$user = User::find(1);
App\User {
    email: "yamada.taro@example.net",
    status: "0",
}
$user->id;    // 1

$newUser = $user->replicate();
App\User {
    email: "yamada.taro@example.net",
    status: "0",
}
$newUser->email = "nakamura.taro@exmaple.co.jp";
$newUser->save();

$newUser->id;     // 52
```

## 10. `find()` で特定の属性を取得
`find()` or `findOrFail()` で特定の属性のみ取得できます。

```python
use App\User;
$user = User::find(1, ['email', 'status']);
# App\User {
#     email: "test30@exmaple.co.jp",
#     status: "0",
# }

$user = User::findOrFail(1, ['email', 'status']);
# App\User {
#     email: "test30@exmaple.co.jp",
#     status: "0",
# }
```