Is there any way to easily clone an Eloquent object, including all of its relationships?
For example, if I had these tables:
users ( id, name, email
You may try this (Object Cloning):
$user = User::find(1);
$new_user = clone $user;
Since clone
doesn't deep copy so child objects won't be copied if there is any child object available and in this case you need to copy the child object using clone
manually. For example:
$user = User::with('role')->find(1);
$new_user = clone $user; // copy the $user
$new_user->role = clone $user->role; // copy the $user->role
In your case roles
will be a collection of Role
objects so each Role object
in the collection needs to be copied manually using clone
.
Also, you need to be aware of that, if you don't load the roles
using with
then those will be not loaded or won't be available in the $user
and when you'll call $user->roles
then those objects will be loaded at run time after that call of $user->roles
and until this, those roles
are not loaded.
This answer was for Larave-4
and now Laravel offers replicate()
method, for example:
$user = User::find(1);
$newUser = $user->replicate();
// ...
For Laravel 5. Tested with hasMany relation.
$model = User::find($id);
$model->load('invoices');
$newModel = $model->replicate();
$newModel->push();
foreach($model->getRelations() as $relation => $items){
foreach($items as $item){
unset($item->id);
$newModel->{$relation}()->create($item->toArray());
}
}
If you have a collection named $user, using the code bellow, it creates a new Collection identical from the old one, including all the relations:
$new_user = new \Illuminate\Database\Eloquent\Collection ( $user->all() );
this code is for laravel 5.
tested in laravel 4.2 for belongsToMany relationships
if you're in the model:
//copy attributes
$new = $this->replicate();
//save model before you recreate relations (so it has an id)
$new->push();
//reset relations on EXISTING MODEL (this way you can control which ones will be loaded
$this->relations = [];
//load relations on EXISTING MODEL
$this->load('relation1','relation2');
//re-sync everything
foreach ($this->relations as $relationName => $values){
$new->{$relationName}()->sync($values);
}