概要
Laravelではモデルの$fillable配列でマスアサインメントを許可するカラムを指定することができる。
しかし、登録・更新に使用するメソッドによって無視される場合と無視されない場合があるため、注意が必要である。
結論
同じ名前のupdateメソッドでも、モデルのupdateメソッドはfilableが有効となり、クエリビルダのupdateメソッドはfilableが無視されてしまう。
よって、クエリビルダのudpateの使用は避けた方がよいと思われる。
ただし、そのためには使用しているのがモデルのメソッドなのか、クエリビルダのメソッドなのか、をしっかりと把握する必要がある。
また、saveメソッドを使う場合は、必ずfillメソッドで値をセットするべきである。
サンプル | fillableが効く・無視されない (データが保存されない) |
---|---|
Item::create(['name' => 'hoge']); | ○ |
Item::find(1)->update(['name' => 'hoge']); | ○ |
Item::where(['id' => 1])->first()->update(['name' => 'hoge']); | ○ |
Item::find(1)->fill(['name' => 'hoge'])->save(); | ○ |
Item::updateOrCreate(['id'=>1, 'name'=>'hogehoge']) | ○ |
Item::where(['id' => 1])->update(['name' => 'hoge']); | × |
Item::query()->where(['id' => 1])->update(['name' => 'hoge']); | × |
DB::table('items')->where(['id' => 1])->update(['name' => 'hoge']); | × |
$model = Item::find(1); | × |
fillableが効く・無視されない(データが保存されない)メソッド
クエリビルダ(Illuminate\Database\Eloquent\Builder)のインスタンスメソッドcreate
Item::create(['name' => 'hoge']); // 'hoge'は保存されない
※ createはモデルのクラスメソッドに見えるが、内部的にはモデルの__callStaticメソッドが実行され、その中でクエリビルダのインスタンスメソッドcreateがコールされている。
モデルのインスタンスメソッドupdate
Item::find(1)->update(['name' => 'hoge']); // 'hoge'は保存されない
Item::where(['id' => 1])->first()->update(['name' => 'hoge']); // 'hoge'は保存されない
モデルのインスタンスメソッドsave(fillメソッドを使う場合)
$model = Item::find(1);
$model->fill(['name' => 'hoge']) // 'hoge'はセットされない
$model->save(); // 'hoge'は保存されない
クエリビルダ(Illuminate\Database\Eloquent\Builder)のインスタンスメソッドupdateOrCreate
Item::updateOrCreate(['id'=>1, 'name'=>'hoge']); // 'hoge'は保存されない
※ updateOrCreateはモデルのクラスメソッドに見えるが、内部的にはモデルの__callStaticメソッドが実行され、その中でクエリビルダのインスタンスメソッドupdateOrCreateがコールされている。
fillableが効かない・無視される(データが保存される)メソッド
クエリビルダ(Illuminate\Database\Eloquent\Builder)のインスタンスメソッドupdate
Item::where(['id' => 1])->update(['name' => 'hoge']); // 'hoge'は保存される
// query()を使う場合
Item::query()->where(['id' => 1])->update(['name' => 'hoge']); // 'hoge'は保存される
クエリビルダ(\Illuminate\Database\Query\Builder)のインスタンスメソッドupdate
DB::table('items')->where(['id' => 1])->update(['name' => 'hoge']); // 'hoge'は保存される
モデルのインスタンスメソッドsave(fillメソッドを使わない場合)
$model = Item::find(1);
$model->name = 'hoge';
$model->save(); // 'hoge'は保存される