Created
September 27, 2016 08:14
-
-
Save barryvdh/f963f5c67d5cfc23357f1a81b3aad56a to your computer and use it in GitHub Desktop.
PushAll example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Eloquent\Relations\BelongsTo; | |
use Illuminate\Database\Eloquent\Relations\Relation; | |
use Illuminate\Support\Collection; | |
trait PushAll { | |
public function pushAll() | |
{ | |
// Convert attributes to relations | |
foreach ($this->attributes as $key => $value) { | |
if (method_exists($this, $key) && $this->$key() instanceof Relation) { | |
$this->setRelation($key, $value); | |
unset($this->attributes[$key]); | |
} | |
} | |
// Split the relations in BelongsTo and other | |
$belongsToRelations = []; | |
$otherRelations = []; | |
foreach ($this->relations as $name => $model) { | |
if ($this->$name() instanceof BelongsTo) { | |
$belongsToRelations[$name] = $model; | |
} else { | |
$otherRelations[$name] = $model; | |
} | |
} | |
/** | |
* Check the inverse relations first, to set the correct key | |
*/ | |
foreach ($belongsToRelations as $name => $model) { | |
/** @var BelongsTo $rel */ | |
$relation = $this->$name(); | |
$model = $this->convertDataToModel($relation, $model); | |
if (! $this->pushAllModel($model)) { | |
return false; | |
} | |
$relation->associate($model); | |
} | |
if (! $this->save()) { | |
return false; | |
} | |
// To sync all of the relationships to the database, we will simply spin through | |
// the relationships and save each model via this "push" method, which allows | |
// us to recurse into all of these nested relations for the model instance. | |
foreach ($otherRelations as $name => $models) { | |
$models = $models instanceof Collection ? $models->all() : [$models]; | |
foreach (array_filter($models) as $model) { | |
/** @var Relation $rel */ | |
$relation = $this->$name(); | |
$model = $this->convertDataToModel($relation, $model); | |
// Save related model | |
$relation->save($model); | |
if (! $this->pushAllModel($model)) { | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
protected function pushAllModel($model) | |
{ | |
$pushMethod = method_exists($model, 'pushAll') ? 'pushAll' : 'push'; | |
return $model->$pushMethod(); | |
} | |
protected function convertDataToModel(Relation $relation, $data) | |
{ | |
if ($data instanceof Model) { | |
return $data; | |
} | |
return $relation->getRelated()->fill($data); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
Route::get('push', function(){ | |
$user = new User; | |
$user->name = 'Barry'; | |
$user->email = str_random(); | |
$user->password = str_random(); | |
$post = new Post; | |
$post->title = 'Test 1'; | |
$post->body = 'Lorem ipsum'; | |
$user->posts[] = $post; | |
$user->posts[] = [ | |
'title' => 'Test 2', | |
'body' => 'from array', | |
]; | |
$user->pushAll(); | |
$user = $user->fresh('posts'); | |
$user->posts->first()->title = 'Test 1a'; | |
$user->posts[] = [ | |
'title' => 'test 3', | |
'body' => 'lala', | |
]; | |
$user->pushAll(); | |
dump($user->fresh('posts')); | |
return 'ok'; | |
}); | |
Route::get('push2', function(){ | |
$post = new Post; | |
$post->title = 'Test A'; | |
$post->body = 'Lorem ipsum'; | |
$post->user = [ | |
'name' => 'Barry', | |
'email' => str_random(), | |
'password' => str_random(), | |
]; | |
/* | |
$user = new User; | |
$user->name = 'Barry'; | |
$user->email = str_random(); | |
$user->password = str_random(); | |
$post->user = $user;*/ | |
$post->pushAll(); | |
dump($post->fresh('user')); | |
return 'ok'; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment