レコードのコピーという作業は結構起こることです。例えば、Eコーマースのサイトなら、サイズだけが違う商品は、説明などの他の属性はほとんど同じなので、わざわざ新規の商品の情報をすべて手入力というよりは、既存の商品をもとに編集する方がもちろん簡単です。
さて、このレコードのコピー作業、Eloquentではどうやるのでしょう?
tinkerを立ち上げます。
まず、usersのテーブルを空にしましょう。
Psy Shell v0.9.9 (PHP 7.1.14 — cli) by Justin Hileman
>>> User::truncate();
=> Illuminate\Database\Eloquent\Builder {#2862}
>>> User::count();
=> 0
次に、ファクトリーを利用してレコードを1つ作成します。
>>> factory(App\User::class, 1)->create();
=> Illuminate\Database\Eloquent\Collection {#2896
all: [
App\User {#2892
name: "Yessenia Jast",
email: "modesto24@example.org",
updated_at: "2019-01-06 05:13:54",
created_at: "2019-01-06 05:13:54",
id: 1,
},
],
}
>>>
そして、このレコードをcloneして保存。
>>> $user = User::find(1);
=> App\User {#121
id: 1,
name: "Yessenia Jast",
email: "modesto24@example.org",
created_at: "2019-01-06 05:13:54",
updated_at: "2019-01-06 05:13:54",
}
>>> $clone = clone $user;
=> App\User {#2894
id: 1,
name: "Yessenia Jast",
email: "modesto24@example.org",
created_at: "2019-01-06 05:13:54",
updated_at: "2019-01-06 05:13:54",
}
>>> $clone->save();
=> true
>>> User::count();
=> 1
>>>
あれれ、新規のレコードを作成してくれませんね。レコード数はオリジナルのレコードの1個です。$cloneは単に同じDBレコードを違うオブジェクトとしただけなので、$clone->save()は新規登録ではなく既存のレコードの編集となってしまうようです。
正しいやり方は、Eloquentのreplicate()を使用してコピーのオブジェクトを作成します。
>>> $clone = $user->replicate();
=> App\User {#2862
name: "Yessenia Jast",
email: "modesto24@example.org",
}
>>> $clone->email = 'test@example.com';
=> "test@example.com"
>>> $clone->save();
=> true
emailはユニークな値でないとDBの重複エラーとなるので違う値にしてsaveしていることに注意してください。
以下のように、レコードは2つになり、複製が作成されています。
>>> User::all();
=> Illuminate\Database\Eloquent\Collection {#2863
all: [
App\User {#2888
id: 1,
name: "Yessenia Jast",
email: "modesto24@example.org",
created_at: "2019-01-06 05:13:54",
updated_at: "2019-01-06 05:13:54",
},
App\User {#2893
id: 2,
name: "Yessenia Jast",
email: "test@example.com",
created_at: "2019-01-06 05:16:06",
updated_at: "2019-01-06 05:16:06",
},
],
}
メルマガ購読の申し込みはこちらから。
