レコードのコピーという作業は結構起こることです。例えば、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", }, ], }メルマガ購読の申し込みはこちらから。