追記 2024/7/19
@pop-culture-studio様よりコメントでご享受いただき修正。
先に結論
create()
メソッドが記述量が少なく、複数代入から保護できる!
fill()->save()
メソッドはコード量で難あり!(挿入ではなく、更新で使用)
insert()
メソッドはセキュリティ面で難あり!(使わない)
Illuminate\Database\Eloquent\Builder
と
Illuminate\Database\Query\Builder
の違い
この記事について
- Laravel初学者向け
- 今までDB挿入メソッドがごっちゃになっていた人
動作環境・使用するツールや言語
- OS バージョン
Windows11 - ツール
VSCode - フレームワーク
Laravel8
前提として今回の簡単なマイグレーションファイルとモデル
public function up()
{
Schema::create('tests', function (Blueprint $table) {
$table->id();
$table->string('name', 255);
$table->timestamps();
});
}
protected $guarded = [
'id'
];
protected $fillable = [
'name'
];
-
$guarded
Eloquentで書き換え不可能 -
$fillable
Eloquentで書き換え可能
Route::get('/save', [TestController::class, 'save']);
Route::get('/create', [TestController::class, 'create']);
Route::get('/insert', [TestController::class, 'insert']);
create()メソッド
public function create()
{
Test::create([
'name' => 'CreateExample',
]);
}
この状態で/createにアクセスし、DBを確認すると、
id = 1,
name="CreateExample", が挿入される。
次にid
を指定し/createにアクセスすると、、、
public function create()
{
Test::create([
'id' => 10,
'name' => 'CreateExample',
]);
}
id = 2,
name="CreateExample", が挿入される。
10
を指定しているのにもかからわず、2
となる。
$guarded
のおかげで指定したid
ではない値が自動で挿入される
save()メソッド
create
メソッドと同じ挙動ですが、違いはコード量です
public function save()
{
$test = new Test();
$test->fill([
'name' => 'TestExample',
]);
$test->save();
}
この状態で/saveにアクセスし、DBを確認すると、
id = 1,
name="CreateExample", が挿入される。
次にid
を指定し/saveにアクセスすると、、、
public function save()
{
$test = new Test();
$test->fill([
'name' => 'TestExample',
]);
$test->save();
}
id = 2,
name="CreateExample", が挿入される。
10
を指定しているのにもかからわず、2
となる。
$guarded
のおかげで指定したid
ではない値が自動で挿入される
insert()メソッド
public function insert()
{
$test = new Test();
$test::insert([
'name' => 'InsertExample',
]);
}
この状態で/insertにアクセスし、DBを確認すると、
id = 1,
name="CreateExample", が挿入される。
次にid
を指定し/insertにアクセスすると、、、
public function insert()
{
$test = new Test();
$test::insert([
'id' => 10,
'name' => 'InsertExample',
]);
}
id = 10,
name="CreateExample", が挿入される。
insertメソッドではid => 10
を指定すれば、10
となる。
次にコードを変えずにもう一度/insertにアクセスしてみると、、、
PRIMARY KEYが重複していますというエラーが出てしまいます。
insert
メソッドは$guarded
と$fillable
の制約を受けないため、思わぬバグを生む可能性がある
追記 2024/7/19
下記コメントを頂戴し、修正。
メソッドの違いではなく
Illuminate\Database\Eloquent\Builderと
Illuminate\Database\Query\Builderの違い。
Illuminate\Database\Eloquent\Modelから始まり、ModelにないメソッドはEloquent\Builderから探す、Eloquent\BuilderにもなければQuery\Builderから探す、という処理の移行がLaravel内で勝手に行われる。
ここを理解してないとEloquentを使ってるつもりで知らないうちにQuery Builderを使うことになる。
$fillableなどはEloquentの機能なのでQuery Builderに移ったら使えない。
慣れてる人はEloquentのメソッドしか使わずQuery Builderに処理が移らないように気を付けている。
新規作成はcreate()。更新はfill()->save()。
insert() update()は使わない。