diff --git a/src/Database/Relations/AttachOneOrMany.php b/src/Database/Relations/AttachOneOrMany.php index f20c3a336..2cf0c171f 100644 --- a/src/Database/Relations/AttachOneOrMany.php +++ b/src/Database/Relations/AttachOneOrMany.php @@ -110,10 +110,6 @@ public function addEagerConstraints(array $models) */ public function save(Model $model, $sessionKey = null) { - if ($sessionKey === null) { - $this->ensureAttachOneIsSingular(); - } - if (!array_key_exists('is_public', $model->attributes)) { $model->setAttribute('is_public', $this->isPublic()); } @@ -121,10 +117,12 @@ public function save(Model $model, $sessionKey = null) $model->setAttribute('field', $this->relationName); if ($sessionKey === null) { + $this->ensureAttachOneIsSingular(); return parent::save($model); } $this->add($model, $sessionKey); + return $model->save() ? $model : false; } @@ -133,16 +131,16 @@ public function save(Model $model, $sessionKey = null) */ public function create(array $attributes = [], $sessionKey = null) { - if ($sessionKey === null) { - $this->ensureAttachOneIsSingular(); - } - if (!array_key_exists('is_public', $attributes)) { $attributes = array_merge(['is_public' => $this->isPublic()], $attributes); } $attributes['field'] = $this->relationName; + if ($sessionKey === null) { + $this->ensureAttachOneIsSingular(); + } + $model = parent::create($attributes); if ($sessionKey !== null) { @@ -221,6 +219,7 @@ public function add(Model $model, $sessionKey = null) $this->parent->fireEvent('model.relation.add', [$this->relationName, $model]); } else { + $this->ensureAttachOneIsSingular($sessionKey); $this->parent->bindDeferred($this->relationName, $model, $sessionKey); } } @@ -319,9 +318,20 @@ protected function isModelRemovable($model): bool * ensureAttachOneIsSingular ensures AttachOne only has one attachment, * by deleting siblings for singular relations. */ - protected function ensureAttachOneIsSingular() + protected function ensureAttachOneIsSingular($sessionKey = null) { - if ($this instanceof AttachOne && $this->parent->exists) { + if (!$this instanceof AttachOne) { + return; + } + + if ($sessionKey) { + foreach ($this->withDeferred($sessionKey)->get() as $record) { + $this->parent->unbindDeferred($this->relationName, $record, $sessionKey); + } + return; + } + + if ($this->parent->exists) { $this->delete(); } }