diff --git a/src/ApiResources/Transformers/LocationTransformer.php b/src/ApiResources/Transformers/LocationTransformer.php index 35e531d..b44a997 100644 --- a/src/ApiResources/Transformers/LocationTransformer.php +++ b/src/ApiResources/Transformers/LocationTransformer.php @@ -24,7 +24,8 @@ class LocationTransformer extends TransformerAbstract public function transform(Location $location): array { - return $this->mergesIdAttribute($location); + return $this->mergesIdAttribute($location, ['settings' => $location->settings]); + // return $this->mergesIdAttribute($location); } public function includeMedia(Location $location): ?Item diff --git a/src/Classes/AbstractRepository.php b/src/Classes/AbstractRepository.php index d282a84..e8bb56f 100644 --- a/src/Classes/AbstractRepository.php +++ b/src/Classes/AbstractRepository.php @@ -234,6 +234,7 @@ protected function setModelAttributes($model, $saveData) $this->modelsToSave[] = $model; $singularTypes = ['belongsTo', 'hasOne', 'morphOne']; + $pluralTypes = ['hasMany', 'morphMany']; foreach ($saveData as $attribute => $value) { if ($attribute === $model->getKeyName() || !$model->isFillable($attribute)) { continue; @@ -243,14 +244,74 @@ protected function setModelAttributes($model, $saveData) continue; } - $isNested = ($attribute == 'pivot' || ( + $isSingularNested = ($attribute == 'pivot' || ( $model->hasRelation($attribute) && in_array($model->getRelationType($attribute), $singularTypes) )); - if ($isNested && is_array($value) && $model->{$attribute}) { + // Handle singular nested relations (belongsTo, hasOne, morphOne) + if ($isSingularNested && is_array($value) && $model->{$attribute}) { $this->setModelAttributes($model->{$attribute}, $value); - } elseif (!starts_with($attribute, '_')) { + continue; + } + + // Handle plural nested relations (hasMany, morphMany) + if ($model->hasRelation($attribute) && in_array($model->getRelationType($attribute), $pluralTypes) && is_array($value)) { + try { + $relation = $model->{$attribute}(); + $relatedModel = method_exists($relation, 'getModel') ? $relation->getModel() : (method_exists($relation, 'getRelated') ? $relation->getRelated() : null); + if ($relatedModel === null) { + continue; + } + + $relatedKey = $relatedModel->getKeyName(); + $fkName = $model->getForeignKey(); + + $existing = $relation->get()->keyBy($relatedKey)->all(); + + foreach ($value as $attrs) { + if (!is_array($attrs)) { + continue; + } + + if (!empty($attrs[$relatedKey]) && isset($existing[$attrs[$relatedKey]])) { + $rel = $existing[$attrs[$relatedKey]]; + $rel->fill($attrs); + } else { + $rel = new ($relatedModel::class)($attrs); + } + + // Queue wrapper that will set parent's FK and save related model after parent saved + $this->modelsToSave[] = new class($rel, $model, $fkName) { + protected $rel; + protected $parent; + protected $fk; + + public function __construct($rel, $parent, $fk) + { + $this->rel = $rel; + $this->parent = $parent; + $this->fk = $fk; + } + + public function save() + { + if (empty($this->rel->{$this->fk}) && $this->parent->getKey()) { + $this->rel->{$this->fk} = $this->parent->getKey(); + } + + $this->rel->save(); + } + }; + } + } catch (\Throwable $ex) { + // If relation introspection fails, skip gracefully + } + + continue; + } + + if (!starts_with($attribute, '_')) { $model->{$attribute} = $value; } }