LoginSignup
2
1

More than 3 years have passed since last update.

Laravel6 Eloquent で複数代入を使用したupdate()の書き方と注意点

Posted at

初投稿です。
なんか公式のドキュメントに書いていない気がするので書きました。
バージョンはLaravel6で確認してまいすが、5.1~7.*は多分同じ。

複数代入とは

こうじゃなくて。

$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->hoge = 'New Flight Hoge';
$flight->save();

こうするやつ。

App\Flight::find(1)->update([
    'name' => 'New Flight Name',
    'hoge' => 'New Flight Hoge',
]);

update()を使います。
$fillableか$guardedをModelに定義していないとエラーになります。
更新したくない値がリクエストに含まれていても、とりあえずは安心です。

呼ばれてるのはこれ。実はfill()してsave()してるだけ。

\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php
    /**
     * Update the model in the database.
     *
     * @param  array  $attributes
     * @param  array  $options
     * @return bool
     */
    public function update(array $attributes = [], array $options = [])
    {
        if (! $this->exists) {
            return false;
        }

        return $this->fill($attributes)->save($options);
    }

実は二種類あるupdate()

ここが注意点です。
こんな風に書いてしまった場合

App\Flight::where(['id' => 1])->update([
    'name' => 'New Flight Name',
    'hoge' => 'New Flight Hoge',
]);

where()はBuilderを返すので、Builderのupdate()が呼ばれます。

\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php
    /**
     * Update a record in the database.
     *
     * @param  array  $values
     * @return int
     */
    public function update(array $values)
    {
        return $this->toBase()->update($this->addUpdatedAtColumn($values));
    }

こちらは戻り値が「変更された行」ですので、updated_atがないテーブルとかだと、普通に0が返ってきます。(ifで悲しいことになるやつ)
ついでに$fillable$guardedも効きません。
ここに書いてる通り、Modelとか関係ないやつです。

まとめ

EloquentはModelだったりBuilderだったりCollectionだったりするので注意が必要です。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1